diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-01-07 02:33:00 +0000 |
commit | beb116954b9b7f3bb56412b2494b562f02b864b1 (patch) | |
tree | 120e997879884e1b9d93b265221b939d2ef1ade1 /include/asm-m68k | |
parent | 908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff) |
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'include/asm-m68k')
73 files changed, 8914 insertions, 454 deletions
diff --git a/include/asm-m68k/a.out.h b/include/asm-m68k/a.out.h new file mode 100644 index 000000000..eda166277 --- /dev/null +++ b/include/asm-m68k/a.out.h @@ -0,0 +1,26 @@ +#ifndef __M68K_A_OUT_H__ +#define __M68K_A_OUT_H__ + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#ifdef __KERNEL__ + +#define STACK_TOP TASK_SIZE + +#endif + +#endif /* __M68K_A_OUT_H__ */ diff --git a/include/asm-m68k/amifd.h b/include/asm-m68k/amifd.h new file mode 100644 index 000000000..0c13747c3 --- /dev/null +++ b/include/asm-m68k/amifd.h @@ -0,0 +1,57 @@ +#ifndef _ASM_M68K_AMIFD_H +#define _ASM_M68K_AMIFD_H + +/* Definitions for the Amiga floppy driver */ + +#include <linux/fd.h> + +#define FD_MAX_UNITS 4 + +struct fd_data_type { + char *name; /* description of data type */ + int sects; /* sectors per track */ +#ifdef __STDC__ + int (*read_fkt)(int, unsigned char *, unsigned long, int); + void (*write_fkt)(int, unsigned long, unsigned char *, int); +#else + int (*read_fkt)(); /* read whole track */ + void (*write_fkt)(); /* write whole track */ +#endif +}; + +#ifndef ASSEMBLER +/* +** Floppy type descriptions +*/ + +struct fd_drive_type { + unsigned long code; /* code returned from drive */ + char *name; /* description of drive */ + unsigned int tracks; /* number of tracks */ + unsigned int heads; /* number of heads */ + unsigned int read_size; /* raw read size for one track */ + unsigned int write_size; /* raw write size for one track */ + unsigned int sect_mult; /* sectors and gap multiplier (HD = 2) */ + unsigned int precomp1; /* start track for precomp 1 */ + unsigned int precomp2; /* start track for precomp 2 */ + unsigned int step_delay; /* time (in ms) for delay after step */ + unsigned int settle_time; /* time to settle after dir change */ + unsigned int side_time; /* time needed to change sides */ +}; + +struct amiga_floppy_struct { + struct fd_drive_type *type; /* type of floppy for this unit */ + struct fd_data_type *dtype; /* type of floppy for this unit */ + int track; /* current track (-1 == unknown) */ + + int blocks; /* total # blocks on disk */ + int sects; /* number of sectors per track */ + + int disk; /* disk in drive (-1 == unknown) */ + int motor; /* true when motor is at speed */ + int busy; /* true when drive is active */ + int status; /* current error code for unit */ +}; +#endif + +#endif diff --git a/include/asm-m68k/amifdreg.h b/include/asm-m68k/amifdreg.h new file mode 100644 index 000000000..76188bf48 --- /dev/null +++ b/include/asm-m68k/amifdreg.h @@ -0,0 +1,81 @@ +#ifndef _LINUX_AMIFDREG_H +#define _LINUX_AMIFDREG_H + +/* +** CIAAPRA bits (read only) +*/ + +#define DSKRDY (0x1<<5) /* disk ready when low */ +#define DSKTRACK0 (0x1<<4) /* head at track zero when low */ +#define DSKPROT (0x1<<3) /* disk protected when low */ +#define DSKCHANGE (0x1<<2) /* low when disk removed */ + +/* +** CIAAPRB bits (read/write) +*/ + +#define DSKMOTOR (0x1<<7) /* motor on when low */ +#define DSKSEL3 (0x1<<6) /* select drive 3 when low */ +#define DSKSEL2 (0x1<<5) /* select drive 2 when low */ +#define DSKSEL1 (0x1<<4) /* select drive 1 when low */ +#define DSKSEL0 (0x1<<3) /* select drive 0 when low */ +#define DSKSIDE (0x1<<2) /* side selection: 0 = upper, 1 = lower */ +#define DSKDIREC (0x1<<1) /* step direction: 0=in, 1=out (to trk 0) */ +#define DSKSTEP (0x1) /* pulse low to step head 1 track */ + +/* +** DSKBYTR bits (read only) +*/ + +#define DSKBYT (1<<15) /* register contains valid byte when set */ +#define DMAON (1<<14) /* disk DMA enabled */ +#define DISKWRITE (1<<13) /* disk write bit in DSKLEN enabled */ +#define WORDEQUAL (1<<12) /* DSKSYNC register match when true */ +/* bits 7-0 are data */ + +/* +** ADKCON/ADKCONR bits +*/ + +#ifndef SETCLR +#define ADK_SETCLR (1<<15) /* control bit */ +#endif +#define ADK_PRECOMP1 (1<<14) /* precompensation selection */ +#define ADK_PRECOMP0 (1<<13) /* 00=none, 01=140ns, 10=280ns, 11=500ns */ +#define ADK_MFMPREC (1<<12) /* 0=GCR precomp., 1=MFM precomp. */ +#define ADK_WORDSYNC (1<<10) /* enable DSKSYNC auto DMA */ +#define ADK_MSBSYNC (1<<9) /* when 1, enable sync on MSbit (for GCR) */ +#define ADK_FAST (1<<8) /* bit cell: 0=2us (GCR), 1=1us (MFM) */ + +/* +** DSKLEN bits +*/ + +#define DSKLEN_DMAEN (1<<15) +#define DSKLEN_WRITE (1<<14) + +/* +** INTENA/INTREQ bits +*/ + +#define DSKINDEX (0x1<<4) /* DSKINDEX bit */ + +/* +** Misc +*/ + +#define MFM_SYNC 0x4489 /* standard MFM sync value */ + +/* Values for FD_COMMAND */ +#define FD_RECALIBRATE 0x07 /* move to track 0 */ +#define FD_SEEK 0x0F /* seek track */ +#define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */ +#define FD_WRITE 0xC5 /* write with MT, MFM */ +#define FD_SENSEI 0x08 /* Sense Interrupt Status */ +#define FD_SPECIFY 0x03 /* specify HUT etc */ +#define FD_FORMAT 0x4D /* format one track */ +#define FD_VERSION 0x10 /* get version code */ +#define FD_CONFIGURE 0x13 /* configure FIFO operation */ +#define FD_PERPENDICULAR 0x12 /* perpendicular r/w mode */ + +#endif /* _LINUX_AMIFDREG_H */ diff --git a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h new file mode 100644 index 000000000..f8268fa7d --- /dev/null +++ b/include/asm-m68k/amigahw.h @@ -0,0 +1,247 @@ +/* +** asm-m68k/amigahw.h -- This header defines some macros and pointers for +** the various Amiga custom hardware registers. +** The naming conventions used here conform to those +** used in the Amiga Hardware Reference Manual, 3rd Edition +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created: 9/24/92 by Greg Harp +*/ + +#ifndef _ASMm68k_AMIGAHW_H_ +#define _ASMm68k_AMIGAHW_H_ + +struct CUSTOM { + u_short bltddat; + u_short dmaconr; + u_short vposr; + u_short vhposr; + u_short dskdatr; + u_short joy0dat; + u_short joy1dat; + u_short clxdat; + u_short adkconr; + u_short pot0dat; + u_short pot1dat; + u_short potgor; + u_short serdatr; + u_short dskbytr; + u_short intenar; + u_short intreqr; + u_char *dskptr; + u_short dsklen; + u_short dskdat; + u_short refptr; + u_short vposw; + u_short vhposw; + u_short copcon; + u_short serdat; + u_short serper; + u_short potgo; + u_short joytest; + u_short strequ; + u_short strvbl; + u_short strhor; + u_short strlong; + u_short bltcon0; + u_short bltcon1; + u_short bltafwm; + u_short bltalwm; + u_char *bltcpt; + u_char *bltbpt; + u_char *bltapt; + u_char *bltdpt; + u_short bltsize; + u_char pad2d; + u_char bltcon0l; + u_short bltsizv; + u_short bltsizh; + u_short bltcmod; + u_short bltbmod; + u_short bltamod; + u_short bltdmod; + u_short spare2[4]; + u_short bltcdat; + u_short bltbdat; + u_short bltadat; + u_short spare3[3]; + u_short deniseid; + u_short dsksync; + u_short *cop1lc; + u_short *cop2lc; + u_short copjmp1; + u_short copjmp2; + u_short copins; + u_short diwstrt; + u_short diwstop; + u_short ddfstrt; + u_short ddfstop; + u_short dmacon; + u_short clxcon; + u_short intena; + u_short intreq; + u_short adkcon; + struct { + u_short *audlc; + u_short audlen; + u_short audper; + u_short audvol; + u_short auddat; + u_short audspare[2]; + } aud[4]; + u_char *bplpt[8]; + u_short bplcon0; + u_short bplcon1; + u_short bplcon2; + u_short bplcon3; + u_short bpl1mod; + u_short bpl2mod; + u_short bplcon4; + u_short clxcon2; + u_short bpldat[8]; + u_char *sprpt[8]; + struct { + u_short pos; + u_short ctl; + u_short dataa; + u_short datab; + } spr[8]; + u_short color[32]; + u_short htotal; + u_short hsstop; + u_short hbstrt; + u_short hbstop; + u_short vtotal; + u_short vsstop; + u_short vbstrt; + u_short vbstop; + u_short sprhstrt; + u_short sprhstop; + u_short bplhstrt; + u_short bplhstop; + u_short hhposw; + u_short hhposr; + u_short beamcon0; + u_short hsstrt; + u_short vsstrt; + u_short hcenter; + u_short diwhigh; + u_short spare4[11]; + u_short fmode; +}; + +/* + * DMA register bits + */ +#define DMAF_SETCLR (0x8000) +#define DMAF_AUD0 (0x0001) +#define DMAF_AUD1 (0x0002) +#define DMAF_AUD2 (0x0004) +#define DMAF_AUD3 (0x0008) +#define DMAF_DISK (0x0010) +#define DMAF_SPRITE (0x0020) +#define DMAF_BLITTER (0x0040) +#define DMAF_COPPER (0x0080) +#define DMAF_RASTER (0x0100) +#define DMAF_MASTER (0x0200) +#define DMAF_BLITHOG (0x0400) +#define DMAF_BLTNZERO (0x2000) +#define DMAF_BLTDONE (0x4000) +#define DMAF_ALL (0x01FF) + +struct CIA { + u_char pra; char pad0[0xff]; + u_char prb; char pad1[0xff]; + u_char ddra; char pad2[0xff]; + u_char ddrb; char pad3[0xff]; + u_char talo; char pad4[0xff]; + u_char tahi; char pad5[0xff]; + u_char tblo; char pad6[0xff]; + u_char tbhi; char pad7[0xff]; + u_char todlo; char pad8[0xff]; + u_char todmid; char pad9[0xff]; + u_char todhi; char pada[0x1ff]; + u_char sdr; char padb[0xff]; + u_char icr; char padc[0xff]; + u_char cra; char padd[0xff]; + u_char crb; char pade[0xff]; +}; + +#if 1 +#define zTwoBase (0x80000000) +#define ZTWO_PADDR(x) (((unsigned long)(x))-zTwoBase) +#define ZTWO_VADDR(x) (((unsigned long)(x))+zTwoBase) +#else +#define zTwoBase 0 +#define ZTWO_PADDR(x) (x) +#define ZTWO_VADDR(x) (x) +#endif + +#define CUSTOM_PHYSADDR (0xdff000) +#define custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR))) + +#define CIAA_PHYSADDR (0xbfe001) +#define CIAB_PHYSADDR (0xbfd000) +#define ciaa ((*(volatile struct CIA *)(zTwoBase + CIAA_PHYSADDR))) +#define ciab ((*(volatile struct CIA *)(zTwoBase + CIAB_PHYSADDR))) + +#define CHIP_PHYSADDR (0x000000) +#define chipaddr ((unsigned long)(zTwoBase + CHIP_PHYSADDR)) +void amiga_chip_init (void); +void *amiga_chip_alloc (long size); +void amiga_chip_free (void *); +unsigned long amiga_chip_avail( void ); /*MILAN*/ + +struct tod3000 { + unsigned int :28, second2:4; /* lower digit */ + unsigned int :28, second1:4; /* upper digit */ + unsigned int :28, minute2:4; /* lower digit */ + unsigned int :28, minute1:4; /* upper digit */ + unsigned int :28, hour2:4; /* lower digit */ + unsigned int :28, hour1:4; /* upper digit */ + unsigned int :28, weekday:4; + unsigned int :28, day2:4; /* lower digit */ + unsigned int :28, day1:4; /* upper digit */ + unsigned int :28, month2:4; /* lower digit */ + unsigned int :28, month1:4; /* upper digit */ + unsigned int :28, year2:4; /* lower digit */ + unsigned int :28, year1:4; /* upper digit */ + unsigned int :28, cntrl1:4; /* control-byte 1 */ + unsigned int :28, cntrl2:4; /* control-byte 2 */ + unsigned int :28, cntrl3:4; /* control-byte 3 */ +}; +#define TOD3000_CNTRL1_HOLD 0 +#define TOD3000_CNTRL1_FREE 9 +#define TOD_3000 ((struct tod3000 *)(zTwoBase+0xDC0000)) + +struct tod2000 { + unsigned int :28, second2:4; /* lower digit */ + unsigned int :28, second1:4; /* upper digit */ + unsigned int :28, minute2:4; /* lower digit */ + unsigned int :28, minute1:4; /* upper digit */ + unsigned int :28, hour2:4; /* lower digit */ + unsigned int :28, hour1:4; /* upper digit */ + unsigned int :28, day2:4; /* lower digit */ + unsigned int :28, day1:4; /* upper digit */ + unsigned int :28, month2:4; /* lower digit */ + unsigned int :28, month1:4; /* upper digit */ + unsigned int :28, year2:4; /* lower digit */ + unsigned int :28, year1:4; /* upper digit */ + unsigned int :28, weekday:4; + unsigned int :28, cntrl1:4; /* control-byte 1 */ + unsigned int :28, cntrl2:4; /* control-byte 2 */ + unsigned int :28, cntrl3:4; /* control-byte 3 */ +}; + +#define TOD2000_CNTRL1_HOLD (1<<0) +#define TOD2000_CNTRL1_BUSY (1<<1) +#define TOD2000_CNTRL3_24HMODE (1<<2) +#define TOD2000_HOUR1_PM (1<<2) +#define TOD_2000 ((struct tod2000 *)(zTwoBase+0xDC0000)) + +#endif /* asm-m68k/amigahw.h */ diff --git a/include/asm-m68k/amigaints.h b/include/asm-m68k/amigaints.h new file mode 100644 index 000000000..0c225ee7c --- /dev/null +++ b/include/asm-m68k/amigaints.h @@ -0,0 +1,123 @@ +/* +** amigaints.h -- Amiga Linux interrupt handling structs and prototypes +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 10/2/92 by Greg Harp +*/ + +#ifndef _ASMm68k_AMIGAINTS_H_ +#define _ASMm68k_AMIGAINTS_H_ + +/* +** Amiga Interrupt sources. +** +*/ + +#define AMI_IRQS (24) +#define AMI_STD_IRQS (14) +#define CIA_IRQS (5) + +/* vertical blanking interrupt */ +#define IRQ_AMIGA_VERTB (IRQ_MACHSPEC | 0) + +/* copper interrupt */ +#define IRQ_AMIGA_COPPER (IRQ_MACHSPEC | 1) + +/* Audio interrupts */ +#define IRQ_AMIGA_AUD0 (IRQ_MACHSPEC | 2) +#define IRQ_AMIGA_AUD1 (IRQ_MACHSPEC | 3) +#define IRQ_AMIGA_AUD2 (IRQ_MACHSPEC | 4) +#define IRQ_AMIGA_AUD3 (IRQ_MACHSPEC | 5) + +/* Blitter done interrupt */ +#define IRQ_AMIGA_BLIT (IRQ_MACHSPEC | 6) + +/* floppy disk interrupts */ +#define IRQ_AMIGA_DSKSYN (IRQ_MACHSPEC | 7) +#define IRQ_AMIGA_DSKBLK (IRQ_MACHSPEC | 8) + +/* builtin serial port interrupts */ +#define IRQ_AMIGA_RBF (IRQ_MACHSPEC | 9) +#define IRQ_AMIGA_TBE (IRQ_MACHSPEC | 10) + +/* software interrupts */ +#define IRQ_AMIGA_SOFT (IRQ_MACHSPEC | 11) + +/* interrupts from external hardware */ +#define IRQ_AMIGA_PORTS (IRQ_MACHSPEC | 12) +#define IRQ_AMIGA_EXTER (IRQ_MACHSPEC | 13) + +/* CIA interrupt sources */ +#define IRQ_AMIGA_CIAA (IRQ_MACHSPEC | 14) +#define IRQ_AMIGA_CIAA_TA (IRQ_MACHSPEC | 14) +#define IRQ_AMIGA_CIAA_TB (IRQ_MACHSPEC | 15) +#define IRQ_AMIGA_CIAA_ALRM (IRQ_MACHSPEC | 16) +#define IRQ_AMIGA_CIAA_SP (IRQ_MACHSPEC | 17) +#define IRQ_AMIGA_CIAA_FLG (IRQ_MACHSPEC | 18) +#define IRQ_AMIGA_CIAB (IRQ_MACHSPEC | 19) +#define IRQ_AMIGA_CIAB_TA (IRQ_MACHSPEC | 19) +#define IRQ_AMIGA_CIAB_TB (IRQ_MACHSPEC | 20) +#define IRQ_AMIGA_CIAB_ALRM (IRQ_MACHSPEC | 21) +#define IRQ_AMIGA_CIAB_SP (IRQ_MACHSPEC | 22) +#define IRQ_AMIGA_CIAB_FLG (IRQ_MACHSPEC | 23) + +#define IRQ_FLOPPY IRQ_AMIGA_DSKBLK + +/* INTREQR masks */ +#define IRQ1_MASK 0x0007 /* INTREQR mask for IRQ 1 */ +#define IRQ2_MASK 0x0008 /* INTREQR mask for IRQ 2 */ +#define IRQ3_MASK 0x0070 /* INTREQR mask for IRQ 3 */ +#define IRQ4_MASK 0x0780 /* INTREQR mask for IRQ 4 */ +#define IRQ5_MASK 0x1800 /* INTREQR mask for IRQ 5 */ +#define IRQ6_MASK 0x2000 /* INTREQR mask for IRQ 6 */ +#define IRQ7_MASK 0x4000 /* INTREQR mask for IRQ 7 */ + +#define IF_SETCLR 0x8000 /* set/clr bit */ +#define IF_INTEN 0x4000 /* master interrupt bit in INT* registers */ +#define IF_EXTER 0x2000 /* external level 6 and CIA B interrupt */ +#define IF_DSKSYN 0x1000 /* disk sync interrupt */ +#define IF_RBF 0x0800 /* serial receive buffer full interrupt */ +#define IF_AUD3 0x0400 /* audio channel 3 done interrupt */ +#define IF_AUD2 0x0200 /* audio channel 2 done interrupt */ +#define IF_AUD1 0x0100 /* audio channel 1 done interrupt */ +#define IF_AUD0 0x0080 /* audio channel 0 done interrupt */ +#define IF_BLIT 0x0040 /* blitter done interrupt */ +#define IF_VERTB 0x0020 /* vertical blanking interrupt */ +#define IF_COPER 0x0010 /* copper interrupt */ +#define IF_PORTS 0x0008 /* external level 2 and CIA A interrupt */ +#define IF_SOFT 0x0004 /* software initiated interrupt */ +#define IF_DSKBLK 0x0002 /* diskblock DMA finished */ +#define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ + +struct irq_server { + unsigned short count, reentrance; +}; + +extern void amiga_do_irq(int irq, struct pt_regs *fp); +extern void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server); + +/* CIA interrupt control register bits */ + +#define CIA_ICR_TA 0x01 +#define CIA_ICR_TB 0x02 +#define CIA_ICR_ALRM 0x04 +#define CIA_ICR_SP 0x08 +#define CIA_ICR_FLG 0x10 +#define CIA_ICR_ALL 0x1f +#define CIA_ICR_SETCLR 0x80 + +/* to access the interrupt control registers of CIA's use only +** these functions, they behave exactly like the amiga os routines +*/ + +extern struct ciabase ciaa_base, ciab_base; + +extern unsigned char cia_set_irq(struct ciabase *base, unsigned char mask); +extern unsigned char cia_able_irq(struct ciabase *base, unsigned char mask); + +#endif /* asm-m68k/amigaints.h */ diff --git a/include/asm-m68k/amigamouse.h b/include/asm-m68k/amigamouse.h new file mode 100644 index 000000000..7f90cff41 --- /dev/null +++ b/include/asm-m68k/amigamouse.h @@ -0,0 +1,26 @@ +#ifndef _ASMm68k_AMIGAMOUSE_H +#define _ASMm68k_AMIGAMOUSE_H + +/* + * linux/include/asm-m68k/amigamouse.h: header file for Amiga Mouse driver + * by Michael Rausch + */ + +/* +#define MSE_INT_OFF() outb(MSE_DISABLE_INTERRUPTS, MSE_CONTROL_PORT) +#define MSE_INT_ON() outb(MSE_ENABLE_INTERRUPTS, MSE_CONTROL_PORT) +*/ + +struct mouse_status { + unsigned char buttons; + unsigned char latch_buttons; + int dx; + int dy; + int present; + int ready; + int active; + struct wait_queue *wait; + struct fasync_struct *fasyncptr; +}; + +#endif diff --git a/include/asm-m68k/amigardb.h b/include/asm-m68k/amigardb.h new file mode 100644 index 000000000..57032469d --- /dev/null +++ b/include/asm-m68k/amigardb.h @@ -0,0 +1,126 @@ +#ifndef _LINUX_AMIGARDB_H +#define _LINUX_AMIGARDB_H 1 + +#define ULONG u_long +#define LONG long +#define UBYTE u_char + +/* definitions for the Amiga RigidDiskBlock layout, which always starts in + cylinder 0 of a medium. Taken from page 254f of the RKM: Devices */ + +struct RigidDiskBlock { + ULONG rdb_ID; /* 4 character identifier */ + ULONG rdb_SummedLongs; /* size of this checksummed structure */ + LONG rdb_ChkSum; /* block checksum (longword sum to zero) */ + ULONG rdb_HostID; /* SCSI Target ID of host */ + ULONG rdb_BlockBytes; /* size of disk blocks */ + ULONG rdb_Flags; /* see below for defines */ + /* block list heads */ + ULONG rdb_BadBlockList; /* optional bad block list */ + ULONG rdb_PartitionList; /* optional first partition block */ + ULONG rdb_FileSysHeaderList; /* optional file system header block */ + ULONG rdb_DriveInit; /* optional drive-specific init code */ + /* DriveInit(lun,rdb,ior): "C" stk & d0/a0/a1 */ + ULONG rdb_Reserved1[6]; /* set to $ffffffff */ + /* physical drive characteristics */ + ULONG rdb_Cylinders; /* number of drive cylinders */ + ULONG rdb_Sectors; /* sectors per track */ + ULONG rdb_Heads; /* number of drive heads */ + ULONG rdb_Interleave; /* interleave */ + ULONG rdb_Park; /* landing zone cylinder */ + ULONG rdb_Reserved2[3]; + ULONG rdb_WritePreComp; /* starting cylinder: write precompensation */ + ULONG rdb_ReducedWrite; /* starting cylinder: reduced write current */ + ULONG rdb_StepRate; /* drive step rate */ + ULONG rdb_Reserved3[5]; + /* logical drive characteristics */ + ULONG rdb_RDBBlocksLo; /* low block of range reserved for hardblocks */ + ULONG rdb_RDBBlocksHi; /* high block of range for these hardblocks */ + ULONG rdb_LoCylinder; /* low cylinder of partitionable disk area */ + ULONG rdb_HiCylinder; /* high cylinder of partitionable data area */ + ULONG rdb_CylBlocks; /* number of blocks available per cylinder */ + ULONG rdb_AutoParkSeconds; /* zero for no auto park */ + ULONG rdb_HighRDSKBlock; /* highest block used by RDSK */ + /* (not including replacement bad blocks) */ + ULONG rdb_Reserved4; + /* drive identification */ + char rdb_DiskVendor[8]; + char rdb_DiskProduct[16]; + char rdb_DiskRevision[4]; + char rdb_ControllerVendor[8]; + char rdb_ControllerProduct[16]; + char rdb_ControllerRevision[4]; + ULONG rdb_Reserved5[10]; +}; + +#define IDNAME_RIGIDDISK 0x5244534B /* 'RDSK' */ + +#define RDB_LOCATION_LIMIT 16 + +#define RDBFB_LAST 0 /* no disks exist to be configured after */ +#define RDBFF_LAST 0x01L /* this one on this controller */ +#define RDBFB_LASTLUN 1 /* no LUNs exist to be configured greater */ +#define RDBFF_LASTLUN 0x02L /* than this one at this SCSI Target ID */ +#define RDBFB_LASTTID 2 /* no Target IDs exist to be configured */ +#define RDBFF_LASTTID 0x04L /* greater than this one on this SCSI bus */ +#define RDBFB_NORESELECT 3 /* don't bother trying to perform reselection */ +#define RDBFF_NORESELECT 0x08L /* when talking to this drive */ +#define RDBFB_DISKID 4 /* rdb_Disk... identification valid */ +#define RDBFF_DISKID 0x10L +#define RDBFB_CTRLRID 5 /* rdb_Controller... identification valid */ +#define RDBFF_CTRLRID 0x20L + /* added 7/20/89 by commodore: */ +#define RDBFB_SYNCH 6 /* drive supports scsi synchronous mode */ +#define RDBFF_SYNCH 0x40L /* CAN BE DANGEROUS TO USE IF IT DOESN'T! */ + +struct PartitionBlock { + ULONG pb_ID; /* 4 character identifier */ + ULONG pb_SummedLongs; /* size of this checksummed structure */ + LONG pb_ChkSum; /* block checksum (longword sum to zero) */ + ULONG pb_HostID; /* SCSI Target ID of host */ + ULONG pb_Next; /* block number of the next PartitionBlock */ + ULONG pb_Flags; /* see below for defines */ + ULONG pb_Reserved1[2]; + ULONG pb_DevFlags; /* preferred flags for OpenDevice */ + UBYTE pb_DriveName[32]; /* preferred DOS device name: BSTR form */ + /* (not used if this name is in use) */ + ULONG pb_Reserved2[15]; /* filler to 32 longwords */ + ULONG pb_Environment[17]; /* environment vector for this partition */ + ULONG pb_EReserved[15]; /* reserved for future environment vector */ +}; + +#define IDNAME_PARTITION 0x50415254 /* 'PART' */ + +#define PBFB_BOOTABLE 0 /* this partition is intended to be bootable */ +#define PBFF_BOOTABLE 1L /* (expected directories and files exist) */ +#define PBFB_NOMOUNT 1 /* do not mount this partition (e.g. manually */ +#define PBFF_NOMOUNT 2L /* mounted, but space reserved here) */ + +/* this is from <dos/filehandler.h> */ + +#define DE_TABLESIZE 0 /* minimum value is 11 (includes NumBuffers) */ +#define DE_SIZEBLOCK 1 /* in longwords: standard value is 128 */ +#define DE_SECORG 2 /* not used; must be 0 */ +#define DE_NUMHEADS 3 /* # of heads (surfaces). drive specific */ +#define DE_SECSPERBLK 4 /* not used; must be 1 */ +#define DE_BLKSPERTRACK 5 /* blocks per track. drive specific */ +#define DE_RESERVEDBLKS 6 /* unavailable blocks at start. usually 2 */ +#define DE_PREFAC 7 /* not used; must be 0 */ +#define DE_INTERLEAVE 8 /* usually 0 */ +#define DE_LOWCYL 9 /* starting cylinder. typically 0 */ +#define DE_UPPERCYL 10 /* max cylinder. drive specific */ +#define DE_NUMBUFFERS 11 /* starting # of buffers. typically 5 */ +#define DE_MEMBUFTYPE 12 /* type of mem to allocate for buffers. */ +#define DE_BUFMEMTYPE 12 /* same as above, better name + * 1 is public, 3 is chip, 5 is fast */ +#define DE_MAXTRANSFER 13 /* Max number bytes to transfer at a time */ +#define DE_MASK 14 /* Address Mask to block out certain memory */ +#define DE_BOOTPRI 15 /* Boot priority for autoboot */ +#define DE_DOSTYPE 16 /* ASCII (HEX) string showing filesystem type; + * 0X444F5300 is old filesystem, + * 0X444F5301 is fast file system */ +#define DE_BAUD 17 /* Baud rate for serial handler */ +#define DE_CONTROL 18 /* Control word for handler/filesystem */ +#define DE_BOOTBLOCKS 19 /* Number of blocks containing boot code */ + +#endif /* _LINUX_AMIGARDB_H */ diff --git a/include/asm-m68k/amigatypes.h b/include/asm-m68k/amigatypes.h new file mode 100644 index 000000000..21a80d9dc --- /dev/null +++ b/include/asm-m68k/amigatypes.h @@ -0,0 +1,59 @@ +/* +** linux/amigatypes.h -- Types used in Amiga Linux kernel source +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 09/29/92 by Greg Harp +** +** Moved all Zorro definitions to asm/zorro.h which is where they +** really belong - 24/11/95 Jes Sorensen +*/ + +#ifndef _LINUX_AMIGATYPES_H_ +#define _LINUX_AMIGATYPES_H_ + +#ifdef __KERNEL__ /* only if compiling the kernel */ +#include <linux/types.h> +#endif + +/* + * Different models of Amiga + */ +#define AMI_UNKNOWN (0) +#define AMI_500 (1) +#define AMI_500PLUS (2) +#define AMI_600 (3) +#define AMI_1000 (4) +#define AMI_1200 (5) +#define AMI_2000 (6) +#define AMI_2500 (7) +#define AMI_3000 (8) +#define AMI_3000T (9) +#define AMI_3000PLUS (10) +#define AMI_4000 (11) +#define AMI_4000T (12) +#define AMI_CDTV (13) +#define AMI_CD32 (14) +#define AMI_DRACO (15) + +/* + * chipsets + */ +#define CS_STONEAGE (0) +#define CS_OCS (1) +#define CS_ECS (2) +#define CS_AGA (3) + +/* + * Amiga clocks + */ + +extern u_long amiga_masterclock; /* 28 MHz */ +extern u_long amiga_colorclock; /* 3.5 MHz */ +#define amiga_eclock boot_info.bi_amiga.eclock /* 700 kHz */ + +#endif /* asm-m68k/amigatypes.h */ diff --git a/include/asm-m68k/amihdreg.h b/include/asm-m68k/amihdreg.h new file mode 100644 index 000000000..8e5a0d34d --- /dev/null +++ b/include/asm-m68k/amihdreg.h @@ -0,0 +1,31 @@ +#ifndef _LINUX_AMIHDREG_H +#define _LINUX_AMIHDREG_H + +/* + * This file contains some defines for the Amiga IDE hd controller. + * Various sources. Check out some definitions (see comments with + * a ques). + */ + +#define IDE_DISABLE_IRQ 0x02 +#define IDE_ENABLE_IRQ 0x00 + +/* Bases of the hard drive controller */ +#define HD_BASE_A4000 0xdd2020 +#define HD_BASE_A1200 0xda0000 + +/* Offsets from one of the above bases */ +#define AMI_HD_ERROR (0x06) /* see err-bits */ +#define AMI_HD_NSECTOR (0x0a) /* nr of sectors to read/write */ +#define AMI_HD_SECTOR (0x0e) /* starting sector */ +#define AMI_HD_LCYL (0x12) /* starting cylinder */ +#define AMI_HD_HCYL (0x16) /* high byte of starting cyl */ +#define AMI_HD_SELECT (0x1a) /* 101dhhhh , d=drive, hhhh=head */ +#define AMI_HD_STATUS (0x1e) /* see status-bits */ +#define AMI_HD_CMD (0x101a) + +/* These are at different offsets from the base */ +#define HD_A4000_IRQ (0xdd3020) /* MSB = 1, Harddisk is source of interrupt */ +#define HD_A1200_IRQ (0xda9000) /* MSB = 1, Harddisk is source of interrupt */ + +#endif diff --git a/include/asm-m68k/atafd.h b/include/asm-m68k/atafd.h new file mode 100644 index 000000000..8456889ee --- /dev/null +++ b/include/asm-m68k/atafd.h @@ -0,0 +1,12 @@ +#ifndef _ASM_M68K_FD_H +#define _ASM_M68K_FD_H + +/* Definitions for the Atari Floppy driver */ + +struct atari_format_descr { + int track; /* to be formatted */ + int head; /* "" "" */ + int sect_offset; /* offset of first sector */ +}; + +#endif diff --git a/include/asm-m68k/atafdreg.h b/include/asm-m68k/atafdreg.h new file mode 100644 index 000000000..8c4a8d5b6 --- /dev/null +++ b/include/asm-m68k/atafdreg.h @@ -0,0 +1,79 @@ +#ifndef _LINUX_FDREG_H +#define _LINUX_FDREG_H + +/* +** WD1772 stuff + */ + +/* register codes */ + +#define FDCSELREG_STP (0x80) /* command/status register */ +#define FDCSELREG_TRA (0x82) /* track register */ +#define FDCSELREG_SEC (0x84) /* sector register */ +#define FDCSELREG_DTA (0x86) /* data register */ + +/* register names for FDC_READ/WRITE macros */ + +#define FDCREG_CMD 0 +#define FDCREG_STATUS 0 +#define FDCREG_TRACK 2 +#define FDCREG_SECTOR 4 +#define FDCREG_DATA 6 + +/* command opcodes */ + +#define FDCCMD_RESTORE (0x00) /* - */ +#define FDCCMD_SEEK (0x10) /* | */ +#define FDCCMD_STEP (0x20) /* | TYP 1 Commands */ +#define FDCCMD_STIN (0x40) /* | */ +#define FDCCMD_STOT (0x60) /* - */ +#define FDCCMD_RDSEC (0x80) /* - TYP 2 Commands */ +#define FDCCMD_WRSEC (0xa0) /* - " */ +#define FDCCMD_RDADR (0xc0) /* - */ +#define FDCCMD_RDTRA (0xe0) /* | TYP 3 Commands */ +#define FDCCMD_WRTRA (0xf0) /* - */ +#define FDCCMD_FORCI (0xd0) /* - TYP 4 Command */ + +/* command modifier bits */ + +#define FDCCMDADD_SR6 (0x00) /* step rate settings */ +#define FDCCMDADD_SR12 (0x01) +#define FDCCMDADD_SR2 (0x02) +#define FDCCMDADD_SR3 (0x03) +#define FDCCMDADD_V (0x04) /* verify */ +#define FDCCMDADD_H (0x08) /* wait for spin-up */ +#define FDCCMDADD_U (0x10) /* update track register */ +#define FDCCMDADD_M (0x10) /* multiple sector access */ +#define FDCCMDADD_E (0x04) /* head settling flag */ +#define FDCCMDADD_P (0x02) /* precompensation off */ +#define FDCCMDADD_A0 (0x01) /* DAM flag */ + +/* status register bits */ + +#define FDCSTAT_MOTORON (0x80) /* motor on */ +#define FDCSTAT_WPROT (0x40) /* write protected (FDCCMD_WR*) */ +#define FDCSTAT_SPINUP (0x20) /* motor speed stable (Type I) */ +#define FDCSTAT_DELDAM (0x20) /* sector has deleted DAM (Type II+III) */ +#define FDCSTAT_RECNF (0x10) /* record not found */ +#define FDCSTAT_CRC (0x08) /* CRC error */ +#define FDCSTAT_TR00 (0x04) /* Track 00 flag (Type I) */ +#define FDCSTAT_LOST (0x04) /* Lost Data (Type II+III) */ +#define FDCSTAT_IDX (0x02) /* Index status (Type I) */ +#define FDCSTAT_DRQ (0x02) /* DRQ status (Type II+III) */ +#define FDCSTAT_BUSY (0x01) /* FDC is busy */ + + +/* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1 1 -> Side 2 */ +#define DSKSIDE (0x01) + +#define DSKDRVNONE (0x06) +#define DSKDRV0 (0x02) +#define DSKDRV1 (0x04) + +/* step rates */ +#define FDCSTEP_6 0x00 +#define FDCSTEP_12 0x01 +#define FDCSTEP_2 0x02 +#define FDCSTEP_3 0x03 + +#endif diff --git a/include/asm-m68k/atari_SCCserial.h b/include/asm-m68k/atari_SCCserial.h new file mode 100644 index 000000000..fc08d4009 --- /dev/null +++ b/include/asm-m68k/atari_SCCserial.h @@ -0,0 +1,60 @@ +#ifndef _ATARI_SCCSERIAL_H +#define _ATARI_SCCSERIAL_H + +/* Special configuration ioctls for the Atari SCC5380 Serial + * Communications Controller + */ + +/* ioctl command codes */ + +#define TIOCGATSCC 0x54c0 /* get SCC configuration */ +#define TIOCSATSCC 0x54c1 /* set SCC configuration */ +#define TIOCDATSCC 0x54c2 /* reset configuration to defaults */ + +/* Clock sources */ + +#define CLK_RTxC 0 +#define CLK_TRxC 1 +#define CLK_PCLK 2 + +/* baud_bases for the common clocks in the Atari. These are the real + * frequencies divided by 16. + */ + +#define SCC_BAUD_BASE_TIMC 19200 /* 0.3072 MHz from TT-MFP, Timer C */ +#define SCC_BAUD_BASE_BCLK 153600 /* 2.4576 MHz */ +#define SCC_BAUD_BASE_PCLK4 229500 /* 3.6720 MHz */ +#define SCC_BAUD_BASE_PCLK 503374 /* 8.0539763 MHz */ +#define SCC_BAUD_BASE_NONE 0 /* for not connected or unused + * clock sources */ + +/* The SCC configuration structure */ + +struct atari_SCCserial { + unsigned RTxC_base; /* base_baud of RTxC */ + unsigned TRxC_base; /* base_baud of TRxC */ + unsigned PCLK_base; /* base_baud of PCLK, for both channels! */ + struct { + unsigned clksrc; /* CLK_RTxC, CLK_TRxC or CLK_PCLK */ + unsigned divisor; /* divisor for base baud, valid values: + * see below */ + } baud_table[17]; /* For 50, 75, 110, 135, 150, 200, 300, + * 600, 1200, 1800, 2400, 4800, 9600, + * 19200, 38400, 57600 and 115200 bps. The + * last two could be replaced by other + * rates > 38400 if they're not possible. + */ +}; + +/* The following divisors are valid: + * + * - CLK_RTxC: 1 or even (1, 2 and 4 are the direct modes, > 4 use + * the BRG) + * + * - CLK_TRxC: 1, 2 or 4 (no BRG, only direct modes possible) + * + * - CLK_PCLK: >= 4 and even (no direct modes, only BRG) + * + */ + +#endif /* _ATARI_SCCSERIAL_H */ diff --git a/include/asm-m68k/atari_SLM.h b/include/asm-m68k/atari_SLM.h new file mode 100644 index 000000000..42f4fcdd8 --- /dev/null +++ b/include/asm-m68k/atari_SLM.h @@ -0,0 +1,28 @@ + +#ifndef _ATARI_SLM_H +#define _ATARI_SLM_H + +/* Atari SLM laser printer specific ioctls */ + +#define SLMIOGSTAT 0xa100 +#define SLMIOGPSIZE 0xa101 +#define SLMIOGMFEED 0xa102 + +#define SLMIORESET 0xa140 + +#define SLMIOSPSIZE 0xa181 +#define SLMIOSMFEED 0xa182 + +/* Status returning structure (SLMIOGSTAT) */ +struct SLM_status { + int stat; /* numeric status code */ + char str[40]; /* status string */ +}; + +/* Paper size structure (SLMIO[GS]PSIZE) */ +struct SLM_paper_size { + int width; + int height; +}; + +#endif /* _ATARI_SLM_H */ diff --git a/include/asm-m68k/atari_acsi.h b/include/asm-m68k/atari_acsi.h new file mode 100644 index 000000000..31a882fbf --- /dev/null +++ b/include/asm-m68k/atari_acsi.h @@ -0,0 +1,37 @@ +#ifndef _ASM_ATARI_ACSI_H +#define _ASM_ATARI_ACSI_H + +/* Functions exported by drivers/block/acsi.c */ + +void acsi_delay_start( void ); +void acsi_delay_end( long usec ); +int acsi_wait_for_IRQ( unsigned timeout ); +int acsi_wait_for_noIRQ( unsigned timeout ); +int acsicmd_nodma( const char *cmd, int enable); +int acsi_getstatus( void ); +int acsi_extstatus( char *buffer, int cnt ); +void acsi_end_extstatus( void ); +int acsi_extcmd( unsigned char *buffer, int cnt ); + +/* The ACSI buffer is guarantueed to reside in ST-RAM and may be used by other + * drivers that work on the ACSI bus, too. It's data are valid only as long as + * the ST-DMA is locked. */ +extern char *acsi_buffer; +extern unsigned long phys_acsi_buffer; + +/* Utility macros */ + +/* Send one data byte over the bus and set mode for next operation + * with one move.l -- Atari recommends this... + */ + +#define DMA_LONG_WRITE(data,mode) \ + do { \ + *((unsigned long *)&dma_wd.fdc_acces_seccount) = \ + ((data)<<16) | (mode); \ + } while(0) + +#define ENABLE_IRQ() atari_turnon_irq( IRQ_MFP_ACSI ) +#define DISABLE_IRQ() atari_turnoff_irq( IRQ_MFP_ACSI ) + +#endif /* _ASM_ATARI_ACSI_H */ diff --git a/include/asm-m68k/atari_joystick.h b/include/asm-m68k/atari_joystick.h new file mode 100644 index 000000000..bdea2f486 --- /dev/null +++ b/include/asm-m68k/atari_joystick.h @@ -0,0 +1,22 @@ +#ifndef _LINUX_ATARI_JOYSTICK_H +#define _LINUX_ATARI_JOYSTICK_H + +/* + * linux/include/linux/atari_joystick.h + * header file for Atari Joystick driver + * by Robert de Vries (robert@and.nl) on 19Jul93 + */ + +void atari_joystick_interrupt(char*); +int atari_joystick_init(void); +extern int atari_mouse_buttons; + +struct joystick_status { + char fire; + char dir; + int ready; + int active; + struct wait_queue *wait; +}; + +#endif diff --git a/include/asm-m68k/atari_mouse.h b/include/asm-m68k/atari_mouse.h new file mode 100644 index 000000000..003bf2b21 --- /dev/null +++ b/include/asm-m68k/atari_mouse.h @@ -0,0 +1,20 @@ +#ifndef _LINUX_ATARI_MOUSE_H +#define _LINUX_ATARI_MOUSE_H + +/* + * linux/include/linux/atari_mouse.h + * header file for Atari Mouse driver + * by Robert de Vries (robert@and.nl) on 19Jul93 + */ + +struct mouse_status { + char buttons; + short dx; + short dy; + int ready; + int active; + struct wait_queue *wait; + struct fasync_struct *fasyncptr; +}; + +#endif diff --git a/include/asm-m68k/atari_rootsec.h b/include/asm-m68k/atari_rootsec.h new file mode 100644 index 000000000..2e6390f1d --- /dev/null +++ b/include/asm-m68k/atari_rootsec.h @@ -0,0 +1,34 @@ +#ifndef _LINUX_ATARI_ROOTSEC_H +#define _LINUX_ATARI_ROOTSEC_H + +/* + * linux/include/linux/atari_rootsec.h + * definitions for Atari Rootsector layout + * by Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de) + * + * modified for ICD/Supra partitioning scheme restricted to at most 12 + * partitions + * by Guenther Kelleter (guenther@pool.informatik.rwth-aachen.de) + */ + +struct partition_info +{ + u_char flg; /* bit 0: active; bit 7: bootable */ + char id[3]; /* "GEM", "BGM", "XGM", or other */ + u_long st; /* start of partition */ + u_long siz; /* length of partition */ +}; + +struct rootsector +{ + char unused[0x156]; /* room for boot code */ + struct partition_info icdpart[8]; /* info for ICD-partitions 5..12 */ + char unused2[0xc]; + u_long hd_siz; /* size of disk in blocks */ + struct partition_info part[4]; + u_long bsl_st; /* start of bad sector list */ + u_long bsl_cnt; /* length of bad sector list */ + u_short checksum; /* checksum for bootable disks */ +} __attribute__((__packed__)); + +#endif /* _LINUX_ATARI_ROOTSEC_H */ diff --git a/include/asm-m68k/atari_stdma.h b/include/asm-m68k/atari_stdma.h new file mode 100644 index 000000000..ddc92e199 --- /dev/null +++ b/include/asm-m68k/atari_stdma.h @@ -0,0 +1,22 @@ + +#ifndef _atari_stdma_h +#define _atari_stdma_h + + +#include <asm/irq.h> + + +/***************************** Prototypes *****************************/ + +void stdma_lock(void (*handler)(int, void *, struct pt_regs *), void *data); +void stdma_release( void ); +int stdma_others_waiting( void ); +int stdma_islocked( void ); +void *stdma_locked_by( void ); +void stdma_init( void ); + +/************************* End of Prototypes **************************/ + + + +#endif /* _atari_stdma_h */ diff --git a/include/asm-m68k/atarihdreg.h b/include/asm-m68k/atarihdreg.h new file mode 100644 index 000000000..bf0846001 --- /dev/null +++ b/include/asm-m68k/atarihdreg.h @@ -0,0 +1,24 @@ +#ifndef _LINUX_ATAHDREG_H +#define _LINUX_ATAHDREG_H + +/* + * This file contains some defines for the Falcon IDE hd controller. + * Various sources. Check out some definitions (see comments with + * a ques). + */ + +#define ATA_HD_BASE 0xfff00000 + +#define ATA_HD_DATA 0x00 /* _CTL when writing */ +#define ATA_HD_ERROR 0x05 /* see err-bits */ +#define ATA_HD_NSECTOR 0x09 /* nr of sectors to read/write */ +#define ATA_HD_SECTOR 0x0d /* starting sector */ +#define ATA_HD_LCYL 0x11 /* starting cylinder */ +#define ATA_HD_HCYL 0x15 /* high byte of starting cyl */ +#define ATA_HD_CURRENT 0x19 /* 101dhhhh , d=drive, hhhh=head */ +#define ATA_HD_STATUS 0x1d /* see status-bits */ + +#define ATA_HD_CMD 0x39 +#define ATA_HD_ALTSTATUS 0x39 /* same as HD_STATUS but doesn't clear irq */ + +#endif /* _LINUX_ATAHDREG_H */ diff --git a/include/asm-m68k/atarihw.h b/include/asm-m68k/atarihw.h new file mode 100644 index 000000000..3fccb4775 --- /dev/null +++ b/include/asm-m68k/atarihw.h @@ -0,0 +1,708 @@ +/* +** linux/atarihw.h -- This header defines some macros and pointers for +** the various Atari custom hardware registers. +** +** Copyright 1994 by Bjrn Brauel +** +** 5/1/94 Roman Hodek: +** Added definitions for TT specific chips. +** +** 1996-09-13 lars brinkhoff <f93labr@dd.chalmers.se>: +** Finally added definitions for the matrix/codec and the DSP56001 host +** interface. +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _LINUX_ATARIHW_H_ +#define _LINUX_ATARIHW_H_ + +#include <linux/types.h> + +/* Reading the MFP port register gives a machine independent delay, since the + * MFP always has a 8 MHz clock. This avoids problems with the varying length + * of nops on various machines. Somebody claimed that the tstb takes 600 ns. + */ +#define MFPDELAY() \ + __asm__ __volatile__ ( "tstb %0" : : "m" (mfp.par_dt_reg) : "cc" ); + +/* Memory used for screen ram and stdma buffers */ +void atari_stram_init (void); +void *atari_stram_alloc (long size, unsigned long *start_mem ); +void atari_stram_free (void *); + +extern int is_medusa; + +/* Do cache push/invalidate for DMA read/write. This function obeys the + * snooping on some machines (Medusa) and processors: The Medusa itself can + * snoop, but only the '040 can source data from its cache to DMA writes i.e., + * reads from memory). Both '040 and '060 invalidate cache entries on snooped + * DMA reads (i.e., writes to memory). + */ + +#include <linux/mm.h> +#include <asm/pgtable.h> + +static inline void dma_cache_maintenance( unsigned long paddr, + unsigned long len, + int writeflag ) + +{ + if (writeflag) { + if (!is_medusa || CPU_IS_060) + cache_push( paddr, len ); + } + else { + if (!is_medusa) + cache_clear( paddr, len ); + } +} + + +/* +** Shifter + */ +#define ST_LOW 0 +#define ST_MID 1 +#define ST_HIGH 2 +#define TT_LOW 7 +#define TT_MID 4 +#define TT_HIGH 6 + +#define SHF_BAS (0xffff8200) +struct SHIFTER + { + u_char pad1; + u_char bas_hi; + u_char pad2; + u_char bas_md; + u_char pad3; + u_char volatile vcounthi; + u_char pad4; + u_char volatile vcountmid; + u_char pad5; + u_char volatile vcountlow; + u_char volatile syncmode; + u_char pad6; + u_char pad7; + u_char bas_lo; + }; +# define shifter ((*(volatile struct SHIFTER *)SHF_BAS)) + +#define SHF_FBAS (0xffff820e) +struct SHIFTER_F030 + { + u_short off_next; + u_short scn_width; + }; +# define shifter_f030 ((*(volatile struct SHIFTER_F030 *)SHF_FBAS)) + + +#define SHF_TBAS (0xffff8200) +struct SHIFTER_TT { + u_char char_dummy0; + u_char bas_hi; /* video mem base addr, high and mid byte */ + u_char char_dummy1; + u_char bas_md; + u_char char_dummy2; + u_char vcount_hi; /* pointer to currently displayed byte */ + u_char char_dummy3; + u_char vcount_md; + u_char char_dummy4; + u_char vcount_lo; + u_short st_sync; /* ST compatible sync mode register, unused */ + u_char char_dummy5; + u_char bas_lo; /* video mem addr, low byte */ + u_char char_dummy6[2+3*16]; + /* $ffff8240: */ + u_short color_reg[16]; /* 16 color registers */ + u_char st_shiftmode; /* ST compatible shift mode register, unused */ + u_char char_dummy7; + u_short tt_shiftmode; /* TT shift mode register */ + + +}; +#define shifter_tt ((*(volatile struct SHIFTER_TT *)SHF_TBAS)) + +/* values for shifter_tt->tt_shiftmode */ +#define TT_SHIFTER_STLOW 0x0000 +#define TT_SHIFTER_STMID 0x0100 +#define TT_SHIFTER_STHIGH 0x0200 +#define TT_SHIFTER_TTLOW 0x0700 +#define TT_SHIFTER_TTMID 0x0400 +#define TT_SHIFTER_TTHIGH 0x0600 +#define TT_SHIFTER_MODEMASK 0x0700 +#define TT_SHIFTER_NUMMODE 0x0008 +#define TT_SHIFTER_PALETTE_MASK 0x000f +#define TT_SHIFTER_GRAYMODE 0x1000 + +/* 256 TT palette registers */ +#define TT_PALETTE_BASE (0xffff8400) +#define tt_palette ((volatile u_short *)TT_PALETTE_BASE) + +#define TT_PALETTE_RED_MASK 0x0f00 +#define TT_PALETTE_GREEN_MASK 0x00f0 +#define TT_PALETTE_BLUE_MASK 0x000f + +/* +** Falcon030 VIDEL Video Controller +** for description see File 'linux\tools\atari\hardware.txt + */ +#define f030_col ((u_long *) 0xffff9800) +#define f030_xreg ((u_short*) 0xffff8282) +#define f030_yreg ((u_short*) 0xffff82a2) +#define f030_creg ((u_short*) 0xffff82c0) +#define f030_sreg ((u_short*) 0xffff8260) +#define f030_mreg ((u_short*) 0xffff820a) +#define f030_linewidth ((u_short*) 0xffff820e) +#define f030_hscroll ((u_char*) 0xffff8265) + +#define VIDEL_BAS (0xffff8260) +struct VIDEL { + u_short st_shift; + u_short pad1; + u_char xoffset_s; + u_char xoffset; + u_short f_shift; + u_char pad2[0x1a]; + u_short hht; + u_short hbb; + u_short hbe; + u_short hdb; + u_short hde; + u_short hss; + u_char pad3[0x14]; + u_short vft; + u_short vbb; + u_short vbe; + u_short vdb; + u_short vde; + u_short vss; + u_char pad4[0x12]; + u_short control; + u_short mode; +}; +#define videl ((*(volatile struct VIDEL *)VIDEL_BAS)) + +/* +** DMA/WD1772 Disk Controller + */ + +#define FWD_BAS (0xffff8604) +struct DMA_WD + { + u_short fdc_acces_seccount; + u_short dma_mode_status; + u_char dma_vhi; /* Some extended ST-DMAs can handle 32 bit addresses */ + u_char dma_hi; + u_char char_dummy2; + u_char dma_md; + u_char char_dummy3; + u_char dma_lo; + u_short fdc_speed; + }; +# define dma_wd ((*(volatile struct DMA_WD *)FWD_BAS)) +/* alias */ +#define st_dma dma_wd +/* The two highest bytes of an extended DMA as a short; this is a must + * for the Medusa. + */ +#define st_dma_ext_dmahi (*((volatile unsigned short *)0xffff8608)) + +/* +** YM2149 Sound Chip +** access in bytes + */ + +#define YM_BAS (0xffff8800) +struct SOUND_YM + { + u_char rd_data_reg_sel; + u_char char_dummy1; + u_char wd_data; + }; +#define sound_ym ((*(volatile struct SOUND_YM *)YM_BAS)) + +/* TT SCSI DMA */ + +#define TT_SCSI_DMA_BAS (0xffff8700) +struct TT_DMA { + u_char char_dummy0; + u_char dma_addr_hi; + u_char char_dummy1; + u_char dma_addr_hmd; + u_char char_dummy2; + u_char dma_addr_lmd; + u_char char_dummy3; + u_char dma_addr_lo; + u_char char_dummy4; + u_char dma_cnt_hi; + u_char char_dummy5; + u_char dma_cnt_hmd; + u_char char_dummy6; + u_char dma_cnt_lmd; + u_char char_dummy7; + u_char dma_cnt_lo; + u_long dma_restdata; + u_short dma_ctrl; +}; +#define tt_scsi_dma ((*(volatile struct TT_DMA *)TT_SCSI_DMA_BAS)) + +/* TT SCSI Controller 5380 */ + +#define TT_5380_BAS (0xffff8781) +struct TT_5380 { + u_char scsi_data; + u_char char_dummy1; + u_char scsi_icr; + u_char char_dummy2; + u_char scsi_mode; + u_char char_dummy3; + u_char scsi_tcr; + u_char char_dummy4; + u_char scsi_idstat; + u_char char_dummy5; + u_char scsi_dmastat; + u_char char_dummy6; + u_char scsi_targrcv; + u_char char_dummy7; + u_char scsi_inircv; +}; +#define tt_scsi ((*(volatile struct TT_5380 *)TT_5380_BAS)) +#define tt_scsi_regp ((volatile char *)TT_5380_BAS) + + +/* +** Falcon DMA Sound Subsystem + */ + +#define MATRIX_BASE (0xffff8930) +struct MATRIX +{ + u_short source; + u_short destination; + u_char external_frequency_divider; + u_char internal_frequency_divider; +}; +#define matrix (*(volatile struct MATRIX *)MATRIX_BASE) + +#define CODEC_BASE (0xffff8936) +struct CODEC +{ + u_char tracks; + u_char input_source; +#define CODEC_SOURCE_MATRIX 1 +#define CODEC_SOURCE_ADC 2 + u_char adc_source; +#define ADC_SOURCE_RIGHT_PSG 1 +#define ADC_SOURCE_LEFT_PSG 2 + u_char gain; +#define CODEC_GAIN_RIGHT 0x0f +#define CODEC_GAIN_LEFT 0xf0 + u_char attenuation; +#define CODEC_ATTENUATION_RIGHT 0x0f +#define CODEC_ATTENUATION_LEFT 0xf0 + u_char unused1; + u_char status; +#define CODEC_OVERFLOW_RIGHT 1 +#define CODEC_OVERFLOW_LEFT 2 + u_char unused2, unused3, unused4, unused5; + u_char gpio_directions; +#define GPIO_IN 0 +#define GPIO_OUT 1 + u_char unused6; + u_char gpio_data; +}; +#define codec (*(volatile struct CODEC *)CODEC_BASE) + +/* +** Falcon Blitter +*/ + +#define BLT_BAS (0xffff8a00) + +struct BLITTER + { + u_short halftone[16]; + u_short src_x_inc; + u_short src_y_inc; + u_long src_address; + u_short endmask1; + u_short endmask2; + u_short endmask3; + u_short dst_x_inc; + u_short dst_y_inc; + u_long dst_address; + u_short wd_per_line; + u_short ln_per_bb; + u_short hlf_op_reg; + u_short log_op_reg; + u_short lin_nm_reg; + u_short skew_reg; + }; +# define blitter ((*(volatile struct BLITTER *)BLT_BAS)) + + +/* +** SCC Z8530 + */ + +#define SCC_BAS (0xffff8c81) +struct SCC + { + u_char cha_a_ctrl; + u_char char_dummy1; + u_char cha_a_data; + u_char char_dummy2; + u_char cha_b_ctrl; + u_char char_dummy3; + u_char cha_b_data; + }; +# define scc ((*(volatile struct SCC*)SCC_BAS)) + +/* The ESCC (Z85230) in an Atari ST. The channels are reversed! */ +# define st_escc ((*(volatile struct SCC*)0xfffffa31)) +# define st_escc_dsr ((*(volatile char *)0xfffffa39)) + +/* TT SCC DMA Controller (same chip as SCSI DMA) */ + +#define TT_SCC_DMA_BAS (0xffff8c00) +#define tt_scc_dma ((*(volatile struct TT_DMA *)TT_SCC_DMA_BAS)) + +/* +** VIDEL Palette Register + */ + +#define FPL_BAS (0xffff9800) +struct VIDEL_PALETTE + { + u_long reg[256]; + }; +# define videl_palette ((*(volatile struct VIDEL_PALETTE*)FPL_BAS)) + + +/* +** Falcon DSP Host Interface + */ + +#define DSP56K_HOST_INTERFACE_BASE (0xffffa200) +struct DSP56K_HOST_INTERFACE { + u_char icr; +#define DSP56K_ICR_RREQ 0x01 +#define DSP56K_ICR_TREQ 0x02 +#define DSP56K_ICR_HF0 0x08 +#define DSP56K_ICR_HF1 0x10 +#define DSP56K_ICR_HM0 0x20 +#define DSP56K_ICR_HM1 0x40 +#define DSP56K_ICR_INIT 0x80 + + u_char cvr; +#define DSP56K_CVR_HV_MASK 0x1f +#define DSP56K_CVR_HC 0x80 + + u_char isr; +#define DSP56K_ISR_RXDF 0x01 +#define DSP56K_ISR_TXDE 0x02 +#define DSP56K_ISR_TRDY 0x04 +#define DSP56K_ISR_HF2 0x08 +#define DSP56K_ISR_HF3 0x10 +#define DSP56K_ISR_DMA 0x40 +#define DSP56K_ISR_HREQ 0x80 + + u_char ivr; + + union { + u_char b[4]; + u_short w[2]; + u_long l; + } data; +}; +#define dsp56k_host_interface ((*(volatile struct DSP56K_HOST_INTERFACE *)DSP56K_HOST_INTERFACE_BASE)) + +/* +** MFP 68901 + */ + +#define MFP_BAS (0xfffffa01) +struct MFP + { + u_char par_dt_reg; + u_char char_dummy1; + u_char active_edge; + u_char char_dummy2; + u_char data_dir; + u_char char_dummy3; + u_char int_en_a; + u_char char_dummy4; + u_char int_en_b; + u_char char_dummy5; + u_char int_pn_a; + u_char char_dummy6; + u_char int_pn_b; + u_char char_dummy7; + u_char int_sv_a; + u_char char_dummy8; + u_char int_sv_b; + u_char char_dummy9; + u_char int_mk_a; + u_char char_dummy10; + u_char int_mk_b; + u_char char_dummy11; + u_char vec_adr; + u_char char_dummy12; + u_char tim_ct_a; + u_char char_dummy13; + u_char tim_ct_b; + u_char char_dummy14; + u_char tim_ct_cd; + u_char char_dummy15; + u_char tim_dt_a; + u_char char_dummy16; + u_char tim_dt_b; + u_char char_dummy17; + u_char tim_dt_c; + u_char char_dummy18; + u_char tim_dt_d; + u_char char_dummy19; + u_char sync_char; + u_char char_dummy20; + u_char usart_ctr; + u_char char_dummy21; + u_char rcv_stat; + u_char char_dummy22; + u_char trn_stat; + u_char char_dummy23; + u_char usart_dta; + }; +# define mfp ((*(volatile struct MFP*)MFP_BAS)) + +/* TT's second MFP */ + +#define TT_MFP_BAS (0xfffffa81) +# define tt_mfp ((*(volatile struct MFP*)TT_MFP_BAS)) + + +/* TT System Control Unit */ + +#define TT_SCU_BAS (0xffff8e01) +struct TT_SCU { + u_char sys_mask; + u_char char_dummy1; + u_char sys_stat; + u_char char_dummy2; + u_char softint; + u_char char_dummy3; + u_char vmeint; + u_char char_dummy4; + u_char gp_reg1; + u_char char_dummy5; + u_char gp_reg2; + u_char char_dummy6; + u_char vme_mask; + u_char char_dummy7; + u_char vme_stat; +}; +#define tt_scu ((*(volatile struct TT_SCU *)TT_SCU_BAS)) + +/* TT real time clock */ + +#define TT_RTC_BAS (0xffff8961) +struct TT_RTC { + u_char regsel; + u_char dummy; + u_char data; +}; +#define tt_rtc ((*(volatile struct TT_RTC *)TT_RTC_BAS)) + + +/* +** ACIA 6850 + */ +/* constants for the ACIA registers */ + +/* baudrate selection and reset (Baudrate = clock/factor) */ +#define ACIA_DIV1 0 +#define ACIA_DIV16 1 +#define ACIA_DIV64 2 +#define ACIA_RESET 3 + +/* character format */ +#define ACIA_D7E2S (0<<2) /* 7 data, even parity, 2 stop */ +#define ACIA_D7O2S (1<<2) /* 7 data, odd parity, 2 stop */ +#define ACIA_D7E1S (2<<2) /* 7 data, even parity, 1 stop */ +#define ACIA_D7O1S (3<<2) /* 7 data, odd parity, 1 stop */ +#define ACIA_D8N2S (4<<2) /* 8 data, no parity, 2 stop */ +#define ACIA_D8N1S (5<<2) /* 8 data, no parity, 1 stop */ +#define ACIA_D8E1S (6<<2) /* 8 data, even parity, 1 stop */ +#define ACIA_D8O1S (7<<2) /* 8 data, odd parity, 1 stop */ + +/* transmit control */ +#define ACIA_RLTID (0<<5) /* RTS low, TxINT disabled */ +#define ACIA_RLTIE (1<<5) /* RTS low, TxINT enabled */ +#define ACIA_RHTID (2<<5) /* RTS high, TxINT disabled */ +#define ACIA_RLTIDSB (3<<5) /* RTS low, TxINT disabled, send break */ + +/* receive control */ +#define ACIA_RID (0<<7) /* RxINT disabled */ +#define ACIA_RIE (1<<7) /* RxINT enabled */ + +/* status fields of the ACIA */ +#define ACIA_RDRF 1 /* Receive Data Register Full */ +#define ACIA_TDRE (1<<1) /* Transmit Data Register Empty */ +#define ACIA_DCD (1<<2) /* Data Carrier Detect */ +#define ACIA_CTS (1<<3) /* Clear To Send */ +#define ACIA_FE (1<<4) /* Framing Error */ +#define ACIA_OVRN (1<<5) /* Receiver Overrun */ +#define ACIA_PE (1<<6) /* Parity Error */ +#define ACIA_IRQ (1<<7) /* Interrupt Request */ + +#define ACIA_BAS (0xfffffc00) +struct ACIA + { + u_char key_ctrl; + u_char char_dummy1; + u_char key_data; + u_char char_dummy2; + u_char mid_ctrl; + u_char char_dummy3; + u_char mid_data; + }; +# define acia ((*(volatile struct ACIA*)ACIA_BAS)) + +#define TT_DMASND_BAS (0xffff8900) +struct TT_DMASND { + u_char int_ctrl; /* Falcon: Interrupt control */ + u_char ctrl; + u_char pad2; + u_char bas_hi; + u_char pad3; + u_char bas_mid; + u_char pad4; + u_char bas_low; + u_char pad5; + u_char addr_hi; + u_char pad6; + u_char addr_mid; + u_char pad7; + u_char addr_low; + u_char pad8; + u_char end_hi; + u_char pad9; + u_char end_mid; + u_char pad10; + u_char end_low; + u_char pad11[12]; + u_char track_select; /* Falcon */ + u_char mode; + u_char pad12[14]; + /* Falcon only: */ + u_short cbar_src; + u_short cbar_dst; + u_char ext_div; + u_char int_div; + u_char rec_track_select; + u_char dac_src; + u_char adc_src; + u_char input_gain; + u_short output_atten; +}; +# define tt_dmasnd ((*(volatile struct TT_DMASND *)TT_DMASND_BAS)) + +#define DMASND_CTRL_OFF 0x00 +#define DMASND_CTRL_ON 0x01 +#define DMASND_CTRL_REPEAT 0x02 +#define DMASND_MODE_MONO 0x80 +#define DMASND_MODE_STEREO 0x00 +#define DMASND_MODE_8BIT 0x00 +#define DMASND_MODE_16BIT 0x40 /* Falcon only */ +#define DMASND_MODE_6KHZ 0x00 /* Falcon: mute */ +#define DMASND_MODE_12KHZ 0x01 +#define DMASND_MODE_25KHZ 0x02 +#define DMASND_MODE_50KHZ 0x03 + +#define DMASNDSetBase(bufstart) \ + do { \ + tt_dmasnd.bas_hi = (unsigned char)(((bufstart) & 0xff0000) >> 16); \ + tt_dmasnd.bas_mid = (unsigned char)(((bufstart) & 0x00ff00) >> 8); \ + tt_dmasnd.bas_low = (unsigned char) ((bufstart) & 0x0000ff); \ + } while( 0 ) + +#define DMASNDGetAdr() ((tt_dmasnd.addr_hi << 16) + \ + (tt_dmasnd.addr_mid << 8) + \ + (tt_dmasnd.addr_low)) + +#define DMASNDSetEnd(bufend) \ + do { \ + tt_dmasnd.end_hi = (unsigned char)(((bufend) & 0xff0000) >> 16); \ + tt_dmasnd.end_mid = (unsigned char)(((bufend) & 0x00ff00) >> 8); \ + tt_dmasnd.end_low = (unsigned char) ((bufend) & 0x0000ff); \ + } while( 0 ) + + +#define TT_MICROWIRE_BAS (0xffff8922) +struct TT_MICROWIRE { + u_short data; + u_short mask; +}; +# define tt_microwire ((*(volatile struct TT_MICROWIRE *)TT_MICROWIRE_BAS)) + +#define MW_LM1992_ADDR 0x0400 + +#define MW_LM1992_VOLUME(dB) \ + (0x0c0 | ((dB) < -80 ? 0 : (dB) > 0 ? 40 : (((dB) + 80) / 2))) +#define MW_LM1992_BALLEFT(dB) \ + (0x140 | ((dB) < -40 ? 0 : (dB) > 0 ? 20 : (((dB) + 40) / 2))) +#define MW_LM1992_BALRIGHT(dB) \ + (0x100 | ((dB) < -40 ? 0 : (dB) > 0 ? 20 : (((dB) + 40) / 2))) +#define MW_LM1992_TREBLE(dB) \ + (0x080 | ((dB) < -12 ? 0 : (dB) > 12 ? 12 : (((dB) / 2) + 6))) +#define MW_LM1992_BASS(dB) \ + (0x040 | ((dB) < -12 ? 0 : (dB) > 12 ? 12 : (((dB) / 2) + 6))) + +#define MW_LM1992_PSG_LOW 0x000 +#define MW_LM1992_PSG_HIGH 0x001 +#define MW_LM1992_PSG_OFF 0x002 + +#define MSTE_RTC_BAS (0xfffffc21) + +struct MSTE_RTC { + u_char sec_ones; + u_char dummy1; + u_char sec_tens; + u_char dummy2; + u_char min_ones; + u_char dummy3; + u_char min_tens; + u_char dummy4; + u_char hr_ones; + u_char dummy5; + u_char hr_tens; + u_char dummy6; + u_char weekday; + u_char dummy7; + u_char day_ones; + u_char dummy8; + u_char day_tens; + u_char dummy9; + u_char mon_ones; + u_char dummy10; + u_char mon_tens; + u_char dummy11; + u_char year_ones; + u_char dummy12; + u_char year_tens; + u_char dummy13; + u_char mode; + u_char dummy14; + u_char test; + u_char dummy15; + u_char reset; +}; + +#define mste_rtc ((*(volatile struct MSTE_RTC *)MSTE_RTC_BAS)) + +#endif /* linux/atarihw.h */ + diff --git a/include/asm-m68k/atariints.h b/include/asm-m68k/atariints.h new file mode 100644 index 000000000..e2bb42b4c --- /dev/null +++ b/include/asm-m68k/atariints.h @@ -0,0 +1,221 @@ +/* +** atariints.h -- Atari Linux interrupt handling structs and prototypes +** +** Copyright 1994 by Bjrn Brauel +** +** 5/2/94 Roman Hodek: +** TT interrupt definitions added. +** +** 12/02/96: (Roman) +** Adapted to new int handling scheme (see ataints.c); revised numbering +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _LINUX_ATARIINTS_H_ +#define _LINUX_ATARIINTS_H_ + +#include <asm/irq.h> +#include <asm/atarihw.h> + +/* +** Atari Interrupt sources. +** +*/ + +#define STMFP_SOURCE_BASE 8 +#define TTMFP_SOURCE_BASE 24 +#define SCC_SOURCE_BASE 40 +#define VME_SOURCE_BASE 56 +#define VME_MAX_SOURCES 16 + +#define NUM_ATARI_SOURCES (VME_SOURCE_BASE+VME_MAX_SOURCES-STMFP_SOURCE_BASE) + +/* convert vector number to int source number */ +#define IRQ_VECTOR_TO_SOURCE(v) ((v) - ((v) < 0x20 ? 0x18 : (0x40-8))) + +/* convert irq_handler index to vector number */ +#define IRQ_SOURCE_TO_VECTOR(i) ((i) + ((i) < 8 ? 0x18 : (0x40-8))) + +/* interrupt service types */ +#define IRQ_TYPE_SLOW 0 +#define IRQ_TYPE_FAST 1 +#define IRQ_TYPE_PRIO 2 + +#define IRQ_SPURIOUS (IRQ_MACHSPEC | 0) + +/* auto-vector interrupts */ +#define IRQ_AUTO_1 (IRQ_MACHSPEC | 1) +#define IRQ_AUTO_2 (IRQ_MACHSPEC | 2) +#define IRQ_AUTO_3 (IRQ_MACHSPEC | 3) +#define IRQ_AUTO_4 (IRQ_MACHSPEC | 4) +#define IRQ_AUTO_5 (IRQ_MACHSPEC | 5) +#define IRQ_AUTO_6 (IRQ_MACHSPEC | 6) +#define IRQ_AUTO_7 (IRQ_MACHSPEC | 7) + +/* ST-MFP interrupts */ +#define IRQ_MFP_BUSY (IRQ_MACHSPEC | 8) +#define IRQ_MFP_DCD (IRQ_MACHSPEC | 9) +#define IRQ_MFP_CTS (IRQ_MACHSPEC | 10) +#define IRQ_MFP_GPU (IRQ_MACHSPEC | 11) +#define IRQ_MFP_TIMD (IRQ_MACHSPEC | 12) +#define IRQ_MFP_TIMC (IRQ_MACHSPEC | 13) +#define IRQ_MFP_ACIA (IRQ_MACHSPEC | 14) +#define IRQ_MFP_FDC (IRQ_MACHSPEC | 15) +#define IRQ_MFP_ACSI IRQ_MFP_FDC +#define IRQ_MFP_FSCSI IRQ_MFP_FDC +#define IRQ_MFP_IDE IRQ_MFP_FDC +#define IRQ_MFP_TIMB (IRQ_MACHSPEC | 16) +#define IRQ_MFP_SERERR (IRQ_MACHSPEC | 17) +#define IRQ_MFP_SEREMPT (IRQ_MACHSPEC | 18) +#define IRQ_MFP_RECERR (IRQ_MACHSPEC | 19) +#define IRQ_MFP_RECFULL (IRQ_MACHSPEC | 20) +#define IRQ_MFP_TIMA (IRQ_MACHSPEC | 21) +#define IRQ_MFP_RI (IRQ_MACHSPEC | 22) +#define IRQ_MFP_MMD (IRQ_MACHSPEC | 23) + +/* TT-MFP interrupts */ +#define IRQ_TT_MFP_IO0 (IRQ_MACHSPEC | 24) +#define IRQ_TT_MFP_IO1 (IRQ_MACHSPEC | 25) +#define IRQ_TT_MFP_SCC (IRQ_MACHSPEC | 26) +#define IRQ_TT_MFP_RI (IRQ_MACHSPEC | 27) +#define IRQ_TT_MFP_TIMD (IRQ_MACHSPEC | 28) +#define IRQ_TT_MFP_TIMC (IRQ_MACHSPEC | 29) +#define IRQ_TT_MFP_DRVRDY (IRQ_MACHSPEC | 30) +#define IRQ_TT_MFP_SCSIDMA (IRQ_MACHSPEC | 31) +#define IRQ_TT_MFP_TIMB (IRQ_MACHSPEC | 32) +#define IRQ_TT_MFP_SERERR (IRQ_MACHSPEC | 33) +#define IRQ_TT_MFP_SEREMPT (IRQ_MACHSPEC | 34) +#define IRQ_TT_MFP_RECERR (IRQ_MACHSPEC | 35) +#define IRQ_TT_MFP_RECFULL (IRQ_MACHSPEC | 36) +#define IRQ_TT_MFP_TIMA (IRQ_MACHSPEC | 37) +#define IRQ_TT_MFP_RTC (IRQ_MACHSPEC | 38) +#define IRQ_TT_MFP_SCSI (IRQ_MACHSPEC | 39) + +/* SCC interrupts */ +#define IRQ_SCCB_TX (IRQ_MACHSPEC | 40) +#define IRQ_SCCB_STAT (IRQ_MACHSPEC | 42) +#define IRQ_SCCB_RX (IRQ_MACHSPEC | 44) +#define IRQ_SCCB_SPCOND (IRQ_MACHSPEC | 46) +#define IRQ_SCCA_TX (IRQ_MACHSPEC | 48) +#define IRQ_SCCA_STAT (IRQ_MACHSPEC | 50) +#define IRQ_SCCA_RX (IRQ_MACHSPEC | 52) +#define IRQ_SCCA_SPCOND (IRQ_MACHSPEC | 54) + + +#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ +#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ + + +#define MFP_ENABLE 0 +#define MFP_PENDING 1 +#define MFP_SERVICE 2 +#define MFP_MASK 3 + +/* Utility functions for setting/clearing bits in the interrupt registers of + * the MFP. 'type' should be constant, if 'irq' is constant, too, code size is + * reduced. set_mfp_bit() is nonsense for PENDING and SERVICE registers. */ + +static inline int get_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = 1 << (irq & 7); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + return( *reg & mask ); +} + +static inline void set_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = 1 << (irq & 7); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + __asm__ __volatile__ ( "orb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); +} + +static inline void clear_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = ~(1 << (irq & 7)); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + if (type == MFP_PENDING || type == MFP_SERVICE) + __asm__ __volatile__ ( "moveb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); + else + __asm__ __volatile__ ( "andb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); +} + +/* + * {en,dis}able_irq have the usual semantics of temporary blocking the + * interrupt, but not loosing requests that happen between disabling and + * enabling. This is done with the MFP mask registers. + */ + +static inline void atari_enable_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + set_mfp_bit( irq, MFP_MASK ); +} + +static inline void atari_disable_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_MASK ); +} + +/* + * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not + * "stored" + */ + +extern inline void atari_turnon_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + set_mfp_bit( irq, MFP_ENABLE ); +} + +extern inline void atari_turnoff_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_ENABLE ); + clear_mfp_bit( irq, MFP_PENDING ); +} + +extern inline void atari_clear_pending_irq( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_PENDING ); +} + +extern inline int atari_irq_pending( unsigned irq ) + +{ + irq &= ~IRQ_MACHSPEC; + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 ); + return( get_mfp_bit( irq, MFP_PENDING ) ); +} + +unsigned long atari_register_vme_int( void ); +void atari_unregister_vme_int( unsigned long ); + +#endif /* linux/atariints.h */ diff --git a/include/asm-m68k/atarikb.h b/include/asm-m68k/atarikb.h new file mode 100644 index 000000000..18926058f --- /dev/null +++ b/include/asm-m68k/atarikb.h @@ -0,0 +1,40 @@ +/* +** atarikb.h -- This header contains the prototypes of functions of +** the intelligent keyboard of the Atari needed by the +** mouse and joystick drivers. +** +** Copyright 1994 by Robert de Vries +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created: 20 Feb 1994 by Robert de Vries +*/ + +#ifndef _LINUX_ATARIKB_H +#define _LINUX_ATARIKB_H + +void ikbd_write(const char *, int); +void ikbd_mouse_button_action(int mode); +void ikbd_mouse_rel_pos(void); +void ikbd_mouse_abs_pos(int xmax, int ymax); +void ikbd_mouse_kbd_mode(int dx, int dy); +void ikbd_mouse_thresh(int x, int y); +void ikbd_mouse_scale(int x, int y); +void ikbd_mouse_pos_get(int *x, int *y); +void ikbd_mouse_pos_set(int x, int y); +void ikbd_mouse_y0_bot(void); +void ikbd_mouse_y0_top(void); +void ikbd_mouse_disable(void); +void ikbd_joystick_event_on(void); +void ikbd_joystick_event_off(void); +void ikbd_joystick_get_state(void); +void ikbd_joystick_disable(void); + +/* Hook for MIDI serial driver */ +extern void (*atari_MIDI_interrupt_hook) (void); +/* Hook for mouse driver */ +extern void (*atari_mouse_interrupt_hook) (char *); + +#endif /* _LINUX_ATARIKB_H */ diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h new file mode 100644 index 000000000..8ea909203 --- /dev/null +++ b/include/asm-m68k/atomic.h @@ -0,0 +1,42 @@ +#ifndef __ARCH_M68K_ATOMIC__ +#define __ARCH_M68K_ATOMIC__ + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +/* + * We do not have SMP m68k systems, so we don't have to deal with that. + */ + +typedef int atomic_t; + +static __inline__ void atomic_add(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__("addl %1,%0" : : "m" (*v), "id" (i)); +} + +static __inline__ void atomic_sub(atomic_t i, atomic_t *v) +{ + __asm__ __volatile__("subl %1,%0" : : "m" (*v), "id" (i)); +} + +static __inline__ void atomic_inc(atomic_t *v) +{ + __asm__ __volatile__("addql #1,%0" : : "m" (*v)); +} + +static __inline__ void atomic_dec(atomic_t *v) +{ + __asm__ __volatile__("subql #1,%0" : : "m" (*v)); +} + +static __inline__ int atomic_dec_and_test(atomic_t *v) +{ + char c; + __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c) : "m" (*v)); + return c != 0; +} + +#endif /* __ARCH_M68K_ATOMIC __ */ diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h index 901fa48a0..b63496040 100644 --- a/include/asm-m68k/bitops.h +++ b/include/asm-m68k/bitops.h @@ -4,17 +4,14 @@ * Copyright 1992, Linus Torvalds. * * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive + * License. See the file COPYING in the main directory of this archive * for more details. */ /* * Require 68020 or better. * - * They don't use the standard m680x0 bit ordering. - * Instead, the use the standard m680x0 bitfield ordering. - * - * Thus, bit 0 is the MSB of addr; bit 32 is the MSB of (addr+1). + * They use the standard big-endian m680x0 bit ordering. */ extern __inline__ int set_bit(int nr,void * vaddr) @@ -22,7 +19,7 @@ extern __inline__ int set_bit(int nr,void * vaddr) char retval; __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr), "a" (vaddr)); + : "=d" (retval) : "d" (nr^31), "a" (vaddr)); return retval; } @@ -32,7 +29,7 @@ extern __inline__ int clear_bit(int nr, void * vaddr) char retval; __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr), "a" (vaddr)); + : "=d" (retval) : "d" (nr^31), "a" (vaddr)); return retval; } @@ -42,61 +39,57 @@ extern __inline__ int change_bit(int nr, void * vaddr) char retval; __asm__ __volatile__ ("bfchg %2@{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr), "a" (vaddr)); + : "=d" (retval) : "d" (nr^31), "a" (vaddr)); return retval; } extern __inline__ int test_bit(int nr, const void * vaddr) { - char retval; - - __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr), "a" (vaddr)); - - return retval; + return ((1UL << (nr & 31)) & (((const unsigned int *) vaddr)[nr >> 5])) != 0; } -extern inline int find_first_zero_bit(void * vaddr, unsigned size) +extern __inline__ int find_first_zero_bit(void * vaddr, unsigned size) { - unsigned long res; - unsigned long *p; - unsigned long *addr = vaddr; + unsigned long *p = vaddr, *addr = vaddr; + unsigned long allones = ~0UL; + int res; + unsigned long num; if (!size) return 0; - __asm__ __volatile__ (" moveq #-1,d0\n\t" - "1:" - " cmpl %1@+,d0\n\t" - " bne 2f\n\t" - " subql #1,%0\n\t" - " bne 1b\n\t" - " bra 5f\n\t" - "2:" - " movel %1@-,d0\n\t" - " notl d0\n\t" - " bfffo d0{#0,#0},%0\n\t" - "5:" - : "=d" (res), "=a" (p) - : "0" ((size + 31) >> 5), "1" (addr) - : "d0"); - return ((p - addr) << 5) + res; -} - -static inline int find_next_zero_bit (void *vaddr, int size, + + size = (size >> 5) + ((size & 31) > 0); + while (*p++ == allones) + { + if (--size == 0) + return (p - addr) << 5; + } + + num = ~*--p; + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + return ((p - addr) << 5) + (res ^ 31); +} + +extern __inline__ int find_next_zero_bit (void *vaddr, int size, int offset) { unsigned long *addr = vaddr; unsigned long *p = addr + (offset >> 5); - int set = 0, bit = offset & 31, res; + int set = 0, bit = offset & 31UL, res; + + if (offset >= size) + return size; if (bit) { + unsigned long num = ~*p & (~0UL << bit); + /* Look for zero in first longword */ - __asm__("bfffo %1{#0,#0},%0" - : "=d" (set) - : "d" (~*p << bit)); - if (set < (32 - bit)) - return set + offset; + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + if (res < 32) + return (offset & ~31UL) + (res ^ 31); set = 32 - bit; p++; } @@ -109,12 +102,156 @@ static inline int find_next_zero_bit (void *vaddr, int size, * ffz = Find First Zero in word. Undefined if no zero exists, * so code should check against ~0UL first.. */ -extern inline unsigned long ffz(unsigned long word) +extern __inline__ unsigned long ffz(unsigned long word) { + int res; + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" - : "=d" (word) - : "d" (~(word))); - return word; + : "=d" (res) : "d" (~word & -~word)); + return res ^ 31; +} + +/* Bitmap functions for the minix filesystem */ + +extern __inline__ int +minix_find_first_zero_bit (const void *vaddr, unsigned size) +{ + const unsigned short *p = vaddr, *addr = vaddr; + int res; + unsigned short num; + + if (!size) + return 0; + + size = (size >> 4) + ((size & 15) > 0); + while (*p++ == 0xffff) + { + if (--size == 0) + return (p - addr) << 4; + } + + num = ~*--p; + __asm__ __volatile__ ("bfffo %1{#16,#16},%0" + : "=d" (res) : "d" (num & -num)); + return ((p - addr) << 4) + (res ^ 31); +} + +extern __inline__ int +minix_set_bit (int nr, void *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^15), "m" (*(char *)vaddr)); + + return retval; +} + +extern __inline__ int +minix_clear_bit (int nr, void *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^15), "m" (*(char *) vaddr)); + + return retval; +} + +extern __inline__ int +minix_test_bit (int nr, const void *vaddr) +{ + return ((1U << (nr & 15)) & (((const unsigned short *) vaddr)[nr >> 4])) != 0; +} + +/* Bitmap functions for the ext2 filesystem. */ + +extern __inline__ int +ext2_set_bit (int nr, void *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfset %2{%1,#1}; sne %0" + : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr)); + + return retval; +} + +extern __inline__ int +ext2_clear_bit (int nr, void *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfclr %2{%1,#1}; sne %0" + : "=d" (retval) : "d" (nr^7), "m" (*(char *) vaddr)); + + return retval; +} + +extern __inline__ int +ext2_test_bit (int nr, const void *vaddr) +{ + return ((1U << (nr & 7)) & (((const unsigned char *) vaddr)[nr >> 3])) != 0; +} + +extern __inline__ int +ext2_find_first_zero_bit (const void *vaddr, unsigned size) +{ + const unsigned long *p = vaddr, *addr = vaddr; + int res; + + if (!size) + return 0; + + size = (size >> 5) + ((size & 31) > 0); + while (*p++ == ~0UL) + { + if (--size == 0) + return (p - addr) << 5; + } + + --p; + for (res = 0; res < 32; res++) + if (!ext2_test_bit (res, p)) + break; + return (p - addr) * 32 + res; +} + +extern __inline__ int +ext2_find_next_zero_bit (const void *vaddr, unsigned size, unsigned offset) +{ + const unsigned long *addr = vaddr; + const unsigned long *p = addr + (offset >> 5); + int bit = offset & 31UL, res; + + if (offset >= size) + return size; + + if (bit) { + /* Look for zero in first longword */ + for (res = bit; res < 32; res++) + if (!ext2_test_bit (res, p)) + return (p - addr) * 32 + res; + p++; + } + /* No zero yet, search remaining full bytes for a zero */ + res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); + return (p - addr) * 32 + res; +} + +/* Byte swapping. */ + +extern __inline__ unsigned short +swab16 (unsigned short val) +{ + return (val << 8) | (val >> 8); +} + +extern __inline__ unsigned int +swab32 (unsigned int val) +{ + __asm__ ("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); + return val; } #endif /* _M68K_BITOPS_H */ diff --git a/include/asm-m68k/bugs.h b/include/asm-m68k/bugs.h new file mode 100644 index 000000000..5f382dac3 --- /dev/null +++ b/include/asm-m68k/bugs.h @@ -0,0 +1,16 @@ +/* + * include/asm-m68k/bugs.h + * + * Copyright (C) 1994 Linus Torvalds + */ + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +static void check_bugs(void) +{ +} diff --git a/include/asm-m68k/byteorder.h b/include/asm-m68k/byteorder.h new file mode 100644 index 000000000..c6c9fc1e9 --- /dev/null +++ b/include/asm-m68k/byteorder.h @@ -0,0 +1,84 @@ +#ifndef _M68K_BYTEORDER_H +#define _M68K_BYTEORDER_H + +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif + +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD +#endif + +#ifdef __KERNEL__ +#include <linux/config.h> +#include <asm/types.h> + +/* + * In-kernel byte order macros to handle stuff like + * byte-order-dependent filesystems etc. + */ + +#define le16_to_cpu(__val) __swab16(__val) +#define le32_to_cpu(__val) __swab32(__val) +#define cpu_to_le32(__val) __swab32(__val) +#define cpu_to_le16(__val) __swab16(__val) + +extern __inline__ __u16 __swab16 (__u16 val) +{ + return (val << 8) | (val >> 8); +} + +extern __inline__ __u32 __swab32 (__u32 val) +{ + __asm__ ("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); + return val; +} + +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#define cpu_to_be16(x) (x) +#define be16_to_cpu(x) (x) + +#endif + +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +extern unsigned long int ntohl(unsigned long int); +extern unsigned short int ntohs(unsigned short int); +extern unsigned long int htonl(unsigned long int); +extern unsigned short int htons(unsigned short int); + +extern __inline__ unsigned long int __ntohl(unsigned long int); +extern __inline__ unsigned short int __ntohs(unsigned short int); + +extern __inline__ unsigned long int +__ntohl(unsigned long int x) +{ + return x; +} + +extern __inline__ unsigned short int +__ntohs(unsigned short int x) +{ + return x; +} + +#define __htonl(x) __ntohl(x) +#define __htons(x) __ntohs(x) + +#define __constant_htonl(x) (x) +#define __constant_htons(x) (x) +#define __constant_ntohl(x) (x) +#define __constant_ntohs(x) (x) + +#ifdef __OPTIMIZE__ +#define ntohl(x) __ntohl(x) +#define ntohs(x) __ntohs(x) +#define htonl(x) __htonl(x) +#define htons(x) __htons(x) +#endif + +#endif diff --git a/include/asm-m68k/cachectl.h b/include/asm-m68k/cachectl.h new file mode 100644 index 000000000..525978e95 --- /dev/null +++ b/include/asm-m68k/cachectl.h @@ -0,0 +1,14 @@ +#ifndef _M68K_CACHECTL_H +#define _M68K_CACHECTL_H + +/* Definitions for the cacheflush system call. */ + +#define FLUSH_SCOPE_LINE 1 /* Flush a cache line */ +#define FLUSH_SCOPE_PAGE 2 /* Flush a page */ +#define FLUSH_SCOPE_ALL 3 /* Flush the whole cache -- superuser only */ + +#define FLUSH_CACHE_DATA 1 /* Writeback and flush data cache */ +#define FLUSH_CACHE_INSN 2 /* Flush instruction cache */ +#define FLUSH_CACHE_BOTH 3 /* Flush both caches */ + +#endif /* _M68K_CACHECTL_H */ diff --git a/include/asm-m68k/checksum.h b/include/asm-m68k/checksum.h new file mode 100644 index 000000000..6b4976567 --- /dev/null +++ b/include/asm-m68k/checksum.h @@ -0,0 +1,113 @@ +#ifndef _M68K_CHECKSUM_H +#define _M68K_CHECKSUM_H + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * the same as csum_partial_copy, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum); + + +/* + * the same as csum_partial_copy, but copies from user space. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +unsigned int csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum); + + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + */ +static inline unsigned short +ip_fast_csum(unsigned char *iph, unsigned int ihl) +{ + unsigned int sum = 0; + + __asm__ ("subqw #1,%2\n" + "1:\t" + "movel %1@+,%/d0\n\t" + "addxl %/d0,%0\n\t" + "dbra %2,1b\n\t" + "movel %0,%/d0\n\t" + "swap %/d0\n\t" + "addxw %/d0,%0\n\t" + "clrw %/d0\n\t" + "addxw %/d0,%0\n\t" + : "=d" (sum), "=a" (iph), "=d" (ihl) + : "0" (sum), "1" (iph), "2" (ihl) + : "d0"); + return ~sum; +} + +/* + * Fold a partial checksum + */ + +static inline unsigned int csum_fold(unsigned int sum) +{ + unsigned int tmp = sum; + __asm__("swap %1\n\t" + "addw %1, %0\n\t" + "clrw %1\n\t" + "addxw %1, %0" + : "=&d" (sum), "=&d" (tmp) + : "0" (sum), "1" (sum)); + return ~sum; +} + + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ + +static inline unsigned short int +csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, + unsigned short proto, unsigned int sum) +{ + __asm__ ("addl %1,%0\n\t" + "addxl %4,%0\n\t" + "addxl %5,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=&d" (saddr) + : "0" (daddr), "1" (saddr), "d" (len + proto), + "d"(sum)); + return csum_fold(sum); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline unsigned short +ip_compute_csum(unsigned char * buff, int len) +{ + return csum_fold (csum_partial(buff, len, 0)); +} + +#endif /* _M68K_CHECKSUM_H */ diff --git a/include/asm-m68k/delay.h b/include/asm-m68k/delay.h index 804a654b7..731dd0b1a 100644 --- a/include/asm-m68k/delay.h +++ b/include/asm-m68k/delay.h @@ -7,18 +7,13 @@ * Delay routines, using a pre-computed "loops_per_second" value. */ -extern __inline__ void __delay(int loops) +extern __inline__ void __delay(unsigned long loops) { - __asm__("\n\tmovel %0,d0\n1:\tsubql #1,d0\n\tbpls 1b\n" - : /* no outputs */ - : "g" (loops) - : "d0"); + __asm__ __volatile__ ("1: subql #1,%0; jcc 1b" + : "=d" (loops) : "0" (loops)); } /* - * division by multiplication: you don't have to worry about - * loss of precision. - * * Use only for very small delays ( < 1 msec). Should probably use a * lookup table, really, as the multiplications take much too long with * short delays. This is a "reasonable" implementation, though (and the @@ -27,14 +22,23 @@ extern __inline__ void __delay(int loops) */ extern __inline__ void udelay(unsigned long usecs) { - asm ("mulul %1,d0,%0\n\t" - "divul %2,d0,%0" - : "=d" (usecs) - : "d" (usecs), - "i" (1000000), - "0" (loops_per_sec) - : "d0"); + unsigned long tmp; + + usecs *= 4295; /* 2**32 / 1000000 */ + __asm__ ("mulul %2,%0:%1" + : "=d" (usecs), "=d" (tmp) + : "d" (usecs), "1" (loops_per_sec)); __delay(usecs); } +extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) +{ + unsigned long tmp; + + __asm__ ("mulul %2,%0:%1; divul %3,%0:%1" + : "=d" (tmp), "=d" (a) + : "d" (b), "d" (c), "1" (a)); + return a; +} + #endif /* defined(_M68K_DELAY_H) */ diff --git a/include/asm-m68k/dma.h b/include/asm-m68k/dma.h index 2820f20a1..af73a0f6f 100644 --- a/include/asm-m68k/dma.h +++ b/include/asm-m68k/dma.h @@ -1,6 +1,12 @@ #ifndef _M68K_DMA_H #define _M68K_DMA_H 1 -/* dummy for m68k */ +/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k and any + occurrence should be flagged as an error. */ + +#define MAX_DMA_CHANNELS 8 + +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ #endif /* _M68K_DMA_H */ diff --git a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h new file mode 100644 index 000000000..8ccf73858 --- /dev/null +++ b/include/asm-m68k/elf.h @@ -0,0 +1,64 @@ +#ifndef __ASMm68k_ELF_H +#define __ASMm68k_ELF_H + +/* + * ELF register definitions.. + */ + +#include <asm/ptrace.h> +#include <asm/user.h> + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_m68kfp_struct elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x) == EM_68K) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB; +#define ELF_ARCH EM_68K + + /* For SVR4/m68k the function pointer to be registered with + `atexit' is passed in %a1. Although my copy of the ABI has + no such statement, it is actually used on ASV. */ +#define ELF_PLAT_INIT(_r) _r->a1 = 0 + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ + /* Bleech. */ \ + pr_reg[0] = regs->d1; \ + pr_reg[1] = regs->d2; \ + pr_reg[2] = regs->d3; \ + pr_reg[3] = regs->d4; \ + pr_reg[4] = regs->d5; \ + pr_reg[7] = regs->a0; \ + pr_reg[8] = regs->a1; \ + pr_reg[14] = regs->d0; \ + pr_reg[15] = rdusp(); \ + pr_reg[16] = regs->orig_d0; \ + pr_reg[17] = regs->sr; \ + pr_reg[18] = regs->pc; \ + pr_reg[19] = (regs->format << 12) | regs->vector; \ + { \ + struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \ + pr_reg[5] = sw->d6; \ + pr_reg[6] = sw->d7; \ + pr_reg[9] = sw->a2; \ + pr_reg[10] = sw->a3; \ + pr_reg[11] = sw->a4; \ + pr_reg[12] = sw->a5; \ + pr_reg[13] = sw->a6; \ + } + +#endif diff --git a/include/asm-m68k/errno.h b/include/asm-m68k/errno.h new file mode 100644 index 000000000..de8949f56 --- /dev/null +++ b/include/asm-m68k/errno.h @@ -0,0 +1,129 @@ +#ifndef _M68K_ERRNO_H +#define _M68K_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#endif /* _M68K_ERRNO_H */ diff --git a/include/asm-m68k/fcntl.h b/include/asm-m68k/fcntl.h new file mode 100644 index 000000000..c1f6ea405 --- /dev/null +++ b/include/asm-m68k/fcntl.h @@ -0,0 +1,59 @@ +#ifndef _M68K_FCNTL_H +#define _M68K_FCNTL_H + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define FASYNC 020000 /* fcntl, for BSD compatibility */ + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +#endif /* _M68K_FCNTL_H */ diff --git a/include/asm-m68k/font.h b/include/asm-m68k/font.h new file mode 100644 index 000000000..926e7194c --- /dev/null +++ b/include/asm-m68k/font.h @@ -0,0 +1,35 @@ +/* + * asm-m68k/font.h -- `Soft' font definitions + * + * Created 1995 by Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_M68K_FONT_H_ +#define _ASM_M68K_FONT_H_ + +#include <linux/types.h> + + + /* + * Find a font with a specific name + */ + +extern int findsoftfont(char *name, int *width, int *height, u_char *data[]); + + + /* + * Get the default font for a specific screen size + */ + +extern void getdefaultfont(int xres, int yres, char *name[], int *width, + int *height, u_char *data[]); + + +/* Max. length for the name of a predefined font */ +#define MAX_FONT_NAME 32 + +#endif /* _ASM_M68K_FONT_H_ */ diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h new file mode 100644 index 000000000..ab5aaf261 --- /dev/null +++ b/include/asm-m68k/ide.h @@ -0,0 +1,522 @@ +/* + * linux/include/asm-m68k/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* Copyright(c) 1996 Kars de Jong */ +/* Based on the ide driver from 1.2.13pl8 */ + +/* + * Credits (alphabetical): + * + * - Bjoern Brauel + * - Kars de Jong + * - Torsten Ebeling + * - Dwight Engen + * - Thorsten Floeck + * - Roman Hodek + * - Guenther Kelleter + * - Chris Lawrence + * - Michael Rausch + * - Christian Sauer + * - Michael Schmitz + * - Jes Soerensen + * - Michael Thurm + * - Geert Uytterhoeven + */ + +#ifndef _M68K_IDE_H +#define _M68K_IDE_H + +#ifdef __KERNEL__ + +#include <linux/config.h> + +#ifdef CONFIG_AMIGA +#include <asm/amigahw.h> +#include <asm/amihdreg.h> +#include <asm/amigaints.h> +#endif /* CONFIG_AMIGA */ + +#ifdef CONFIG_ATARI +#include <asm/atarihw.h> +#include <asm/atarihdreg.h> +#include <asm/atariints.h> +#include <asm/atari_stdma.h> +#endif /* CONFIG_ATARI */ + +#include <asm/setup.h> +#include <asm/io.h> +#include <asm/irq.h> + +typedef unsigned char * ide_ioreg_t; + +#ifndef MAX_HWIFS +#define MAX_HWIFS 1 +#endif + +static __inline int ide_default_irq (ide_ioreg_t base) +{ + return 0; +} + +static __inline__ ide_ioreg_t ide_default_io_base (int index) +{ + if (index) + return NULL; +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) { + if (AMIGAHW_PRESENT(A4000_IDE)) { + printk("Gayle IDE interface (A%d style)\n", 4000); + return ((ide_ioreg_t)ZTWO_VADDR(HD_BASE_A4000)); + } + if (AMIGAHW_PRESENT(A1200_IDE)) { + printk("Gayle IDE interface (A%d style)\n", 1200); + return ((ide_ioreg_t)ZTWO_VADDR(HD_BASE_A1200)); + } + } +#endif /* CONFIG_AMIGA */ +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + if (ATARIHW_PRESENT(IDE)) { + printk("Falcon IDE interface\n"); + return ((ide_ioreg_t) ATA_HD_BASE); + } + } +#endif /* CONFIG_ATARI */ + return NULL; +} + +static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) +{ + *p++ = base; +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) { + *p++ = base + AMI_HD_ERROR; + *p++ = base + AMI_HD_NSECTOR; + *p++ = base + AMI_HD_SECTOR; + *p++ = base + AMI_HD_LCYL; + *p++ = base + AMI_HD_HCYL; + *p++ = base + AMI_HD_SELECT; + *p++ = base + AMI_HD_STATUS; + *p++ = base + AMI_HD_CMD; + if (AMIGAHW_PRESENT(A4000_IDE)) + *p++ = (ide_ioreg_t) ZTWO_VADDR(HD_A4000_IRQ); + else if (AMIGAHW_PRESENT(A1200_IDE)) + *p++ = (ide_ioreg_t) ZTWO_VADDR(HD_A1200_IRQ); + if (irq != NULL) + *irq = IRQ_AMIGA_PORTS; + } +#endif /* CONFIG_AMIGA */ +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + *p++ = base + ATA_HD_ERROR; + *p++ = base + ATA_HD_NSECTOR; + *p++ = base + ATA_HD_SECTOR; + *p++ = base + ATA_HD_LCYL; + *p++ = base + ATA_HD_HCYL; + *p++ = base + ATA_HD_CURRENT; + *p++ = base + ATA_HD_STATUS; + *p++ = base + ATA_HD_CMD; + if (irq != NULL) + *irq = IRQ_MFP_IDE; + } +#endif /* CONFIG_ATARI */ +} + +typedef union { + unsigned all : 8; /* all of the bits together */ + struct { + unsigned bit7 : 1; /* always 1 */ + unsigned lba : 1; /* using LBA instead of CHS */ + unsigned bit5 : 1; /* always 1 */ + unsigned unit : 1; /* drive select number, 0 or 1 */ + unsigned head : 4; /* always zeros here */ + } b; + } select_t; + +static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *device, void *dev_id) +{ +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) + return request_irq(irq, handler, 0, device, dev_id); +#endif /* CONFIG_AMIGA */ + return 0; +} + +static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) +{ +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) + free_irq(irq, dev_id); +#endif /* CONFIG_AMIGA */ +} + +/* + * We should really implement those some day. + */ +static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) +{ + return 0; +} + +static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name) +{ +} + +static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent) +{ +} + +#undef SUPPORT_SLOW_DATA_PORTS +#define SUPPORT_SLOW_DATA_PORTS 0 + +#undef SUPPORT_VLB_SYNC +#define SUPPORT_VLB_SYNC 0 + +#undef HD_DATA +#define HD_DATA NULL + +#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1) +#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1) + +#define insw(port, buf, nr) \ + if ((nr) % 16) \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a0@,%/a1@+; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "a0", "a1", "d6"); \ + else \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + lsrl #4,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + movew %/a0@,%/a1@+; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "a0", "a1", "d6") + +#define outsw(port, buf, nr) \ + if ((nr) % 16) \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a1@+,%/a0@; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "a0", "a1", "d6"); \ + else \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + lsrl #4,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + movew %/a1@+,%/a0@; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "a0", "a1", "d6") + +#ifdef CONFIG_ATARI +#define insl_swapw(data_reg, buffer, wcount) \ + insw_swapw(data_reg, buffer, (wcount)<<1) +#define outsl_swapw(data_reg, buffer, wcount) \ + outsw_swapw(data_reg, buffer, (wcount)<<1) + +#define insw_swapw(port, buf, nr) \ + if ((nr) % 8) \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "d0", "a0", "a1", "d6"); \ + else \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + lsrl #3,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + movew %/a0@,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a1@+; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "d0", "a0", "a1", "d6") + +#define outsw_swapw(port, buf, nr) \ + if ((nr) % 8) \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "d0", "a0", "a1", "d6"); \ + else \ + __asm__ __volatile__ \ + ("movel %0,%/a0; \ + movel %1,%/a1; \ + movel %2,%/d6; \ + lsrl #3,%/d6; \ + subql #1,%/d6; \ + 1:movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + movew %/a1@+,%/d0; \ + rolw #8,%/d0; \ + movew %/d0,%/a0@; \ + dbra %/d6,1b" : \ + : "g" (port), "g" (buf), "g" (nr) \ + : "d0", "a0", "a1", "d6") + +#endif /* CONFIG_ATARI */ + +static __inline__ int ide_ack_intr (ide_ioreg_t base_port, ide_ioreg_t irq_port) +{ +#ifdef CONFIG_AMIGA + if (MACH_IS_AMIGA) { + unsigned char ch; + ch = inb(irq_port); + if (!(ch & 0x80)) + return(0); + if (AMIGAHW_PRESENT(A1200_IDE)) { + (void) inb(base_port); + outb(0x7c | (ch & 0x03), irq_port); + } + } +#endif /* CONFIG_AMIGA */ + return(1); +} + +#define T_CHAR (0x0000) /* char: don't touch */ +#define T_SHORT (0x4000) /* short: 12 -> 21 */ +#define T_INT (0x8000) /* int: 1234 -> 4321 */ +#define T_TEXT (0xc000) /* text: 12 -> 21 */ + +#define T_MASK_TYPE (0xc000) +#define T_MASK_COUNT (0x3fff) + +#define D_CHAR(cnt) (T_CHAR | (cnt)) +#define D_SHORT(cnt) (T_SHORT | (cnt)) +#define D_INT(cnt) (T_INT | (cnt)) +#define D_TEXT(cnt) (T_TEXT | (cnt)) + +#ifdef CONFIG_AMIGA +static u_short driveid_types[] = { + D_SHORT(10), /* config - vendor2 */ + D_TEXT(20), /* serial_no */ + D_SHORT(3), /* buf_type - ecc_bytes */ + D_TEXT(48), /* fw_rev - model */ + D_CHAR(2), /* max_multsect - vendor3 */ + D_SHORT(1), /* dword_io */ + D_CHAR(2), /* vendor4 - capability */ + D_SHORT(1), /* reserved50 */ + D_CHAR(4), /* vendor5 - tDMA */ + D_SHORT(4), /* field_valid - cur_sectors */ + D_INT(1), /* cur_capacity */ + D_CHAR(2), /* multsect - multsect_valid */ + D_INT(1), /* lba_capacity */ + D_SHORT(194) /* dma_1word - reservedyy */ +}; + +#define num_driveid_types (sizeof(driveid_types)/sizeof(*driveid_types)) +#endif /* CONFIG_AMIGA */ + +static __inline__ void ide_fix_driveid(struct hd_driveid *id) +{ +#ifdef CONFIG_AMIGA + u_char *p = (u_char *)id; + int i, j, cnt; + u_char t; + + if (!MACH_IS_AMIGA) + return; + for (i = 0; i < num_driveid_types; i++) { + cnt = driveid_types[i] & T_MASK_COUNT; + switch (driveid_types[i] & T_MASK_TYPE) { + case T_CHAR: + p += cnt; + break; + case T_SHORT: + for (j = 0; j < cnt; j++) { + t = p[0]; + p[0] = p[1]; + p[1] = t; + p += 2; + } + break; + case T_INT: + for (j = 0; j < cnt; j++) { + t = p[0]; + p[0] = p[3]; + p[3] = t; + t = p[1]; + p[1] = p[2]; + p[2] = t; + p += 4; + } + break; + case T_TEXT: + for (j = 0; j < cnt; j += 2) { + t = p[0]; + p[0] = p[1]; + p[1] = t; + p += 2; + } + break; + } + } +#endif /* CONFIG_AMIGA */ +} + +static __inline__ void ide_release_lock (int *ide_lock) +{ +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + if (*ide_lock == 0) { + printk("ide_release_lock: bug\n"); + return; + } + *ide_lock = 0; + stdma_release(); + } +#endif /* CONFIG_ATARI */ +} + +static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data) +{ +#ifdef CONFIG_ATARI + if (MACH_IS_ATARI) { + if (*ide_lock == 0) { + if (intr_count > 0) + panic( "Falcon IDE hasn't ST-DMA lock in interrupt" ); + stdma_lock(handler, data); + *ide_lock = 1; + } + } +#endif /* CONFIG_ATARI */ +} + +/* + * On the Atari, we sometimes can't enable interrupts: + */ + +/* MSch: changed sti() to STI() wherever possible in ide.c; moved STI() def. + * to asm/ide.h + */ +/* The Atari interrupt structure strictly requires that the IPL isn't lowered + * uncontrolled in an interrupt handler. In the concrete case, the IDE + * interrupt is already a slow int, so the irq is already disabled at the time + * the handler is called, and the IPL has been lowered to the minimum value + * possible. To avoid going below that, STI() checks for being called inside + * an interrupt, and in that case it does nothing. Hope that is reasonable and + * works. (Roman) + */ +#if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) +#define ide_sti() \ + do { \ + if (!intr_count) sti(); \ + } while(0) +#elif defined(CONFIG_ATARI) +#define ide_sti() \ + do { \ + if (!MACH_IS_ATARI || !intr_count) sti(); \ + } while(0) +#else /* !defined(CONFIG_ATARI) */ +#define ide_sti() sti() +#endif + +#endif /* __KERNEL__ */ + +#endif /* _M68K_IDE_H */ diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h index 0cde22fd3..a9d65f743 100644 --- a/include/asm-m68k/io.h +++ b/include/asm-m68k/io.h @@ -1,24 +1,54 @@ #ifndef _M68K_IO_H #define _M68K_IO_H -static inline unsigned char get_user_byte_io(const char * addr) -{ - register unsigned char _v; +#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 m68k 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 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 memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +#define inb_p(addr) readb(addr) +#define inb(addr) readb(addr) - __asm__ __volatile__ ("moveb %1,%0":"=r" (_v):"m" (*addr)); - return _v; +#define outb(x,addr) ((void) writeb(x,addr)) +#define outb_p(x,addr) outb(x,addr) + +/* + * Change virtual addresses to physical addresses and vv. + */ +extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const)); +extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); + +extern inline unsigned long virt_to_phys(volatile void * address) +{ + return mm_vtop((unsigned long)address); } -#define inb_p(addr) get_user_byte_io((char *)(addr)) -#define inb(addr) get_user_byte_io((char *)(addr)) -static inline void put_user_byte_io(char val,char *addr) +extern inline void * phys_to_virt(unsigned long address) { - __asm__ __volatile__ ("moveb %0,%1" - : /* no outputs */ - :"r" (val),"m" (*addr) - : "memory"); + return (void *) mm_ptov(address); } -#define outb_p(x,addr) put_user_byte_io((x),(char *)(addr)) -#define outb(x,addr) put_user_byte_io((x),(char *)(addr)) + +/* + * IO bus memory addresses are 1:1 with the physical address + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +#endif /* __KERNEL__ */ #endif /* _M68K_IO_H */ diff --git a/include/asm-m68k/ioctl.h b/include/asm-m68k/ioctl.h new file mode 100644 index 000000000..385aa8c7f --- /dev/null +++ b/include/asm-m68k/ioctl.h @@ -0,0 +1,80 @@ +/* $Id: ioctl.h,v 1.1 1996/08/24 12:43:44 root Exp $ + * + * linux/ioctl.h for Linux by H.H. Bergman. + */ + +#ifndef _M68K_IOCTL_H +#define _M68K_IOCTL_H + +/* ioctl command encoding: 32 bits total, command in lower 16 bits, + * size of the parameter structure in the lower 14 bits of the + * upper 16 bits. + * Encoding the size of the parameter structure in the ioctl request + * is useful for catching programs compiled with old versions + * and to avoid overwriting user space outside the user buffer area. + * The highest 2 bits are reserved for indicating the ``access mode''. + * NOTE: This limits the max parameter size to 16kB -1 ! + */ + +/* + * I don't really have any idea about what this should look like, so + * for the time being, this is heavily based on the PC definitions. + */ + +/* + * The following is for compatibility across the various Linux + * platforms. The i386 ioctl numbering scheme doesn't really enforce + * a type field. De facto, however, the top 8 bits of the lower 16 + * bits are indeed used as a type field, so we might just as well make + * this explicit here. Please be sure to use the decoding macros + * below from now on. + */ +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits. + */ +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode ioctl numbers.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* ...and for the drivers/sound files... */ + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _M68K_IOCTL_H */ diff --git a/include/asm-m68k/ioctls.h b/include/asm-m68k/ioctls.h new file mode 100644 index 000000000..77ad866b8 --- /dev/null +++ b/include/asm-m68k/ioctls.h @@ -0,0 +1,74 @@ +#ifndef __ARCH_M68K_IOCTLS_H__ +#define __ARCH_M68K_IOCTLS_H__ + +#include <asm/ioctl.h> + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* __ARCH_M68K_IOCTLS_H__ */ diff --git a/include/asm-m68k/ipc.h b/include/asm-m68k/ipc.h new file mode 100644 index 000000000..f1a75cc1d --- /dev/null +++ b/include/asm-m68k/ipc.h @@ -0,0 +1,28 @@ +#ifndef __m68k_IPC_H__ +#define __m68k_IPC_H__ + +/* + * These are used to wrap system calls on m68k. + * + * See arch/m68k/kernel/sys_m68k.c for ugly details.. + */ +struct ipc_kludge { + struct msgbuf *msgp; + long msgtyp; +}; + +#define SEMOP 1 +#define SEMGET 2 +#define SEMCTL 3 +#define MSGSND 11 +#define MSGRCV 12 +#define MSGGET 13 +#define MSGCTL 14 +#define SHMAT 21 +#define SHMDT 22 +#define SHMGET 23 +#define SHMCTL 24 + +#define IPCCALL(version,op) ((version)<<16 | (op)) + +#endif diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h index c8f300ca8..7789be42f 100644 --- a/include/asm-m68k/irq.h +++ b/include/asm-m68k/irq.h @@ -1,6 +1,101 @@ #ifndef _M68K_IRQ_H_ #define _M68K_IRQ_H_ -/* dummy for m68k */ +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +#include <linux/config.h> + +/* + * # of m68k interrupts + */ + +#define SYS_IRQS 8 + +/* + * This should be the same as the max(NUM_X_SOURCES) for all the + * different m68k hosts compiled into the kernel. + * Currently the Atari has 72 and the Amiga 24, but if both are + * supported in the kernel it is better to make room for 72. + */ +#if defined(CONFIG_ATARI) +#define NR_IRQS (72+SYS_IRQS) +#else +#define NR_IRQS (24+SYS_IRQS) +#endif + +/* + * Interrupt source definitions + * General interrupt sources are the level 1-7. + * Adding an interrupt service routine for one of these sources + * results in the addition of that routine to a chain of routines. + * Each one is called in succession. Each individual interrupt + * service routine should determine if the device associated with + * that routine requires service. + */ + +#define IRQ1 (1) /* level 1 interrupt */ +#define IRQ2 (2) /* level 2 interrupt */ +#define IRQ3 (3) /* level 3 interrupt */ +#define IRQ4 (4) /* level 4 interrupt */ +#define IRQ5 (5) /* level 5 interrupt */ +#define IRQ6 (6) /* level 6 interrupt */ +#define IRQ7 (7) /* level 7 interrupt (non-maskable) */ + +/* + * "Generic" interrupt sources + */ + +#define IRQ_SCHED_TIMER (8) /* interrupt source for scheduling timer */ + +/* + * Machine specific interrupt sources. + * + * Adding an interrupt service routine for a source with this bit + * set indicates a special machine specific interrupt source. + * The machine specific files define these sources. + */ + +#define IRQ_MACHSPEC (0x10000000L) +#define IRQ_IDX(irq) ((irq) & ~IRQ_MACHSPEC) + +/* + * various flags for request_irq() + */ +#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ +#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ +#define IRQ_FLG_FAST (0x0004) +#define IRQ_FLG_SLOW (0x0008) +#define IRQ_FLG_STD (0x8000) /* internally used */ + +/* + * This structure is used to chain together the ISRs for a particular + * interrupt source (if it supports chaining). + */ +typedef struct irq_node { + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; + struct irq_node *next; +} irq_node_t; + +/* + * This structure has only 4 elements for speed reasons + */ +typedef struct irq_handler { + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; +} irq_handler_t; + +/* count of spurious interrupts */ +extern volatile unsigned int num_spurious; + +/* + * This function returns a new irq_node_t + */ +extern irq_node_t *new_irq_node(void); #endif /* _M68K_IRQ_H_ */ diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h new file mode 100644 index 000000000..68302fe60 --- /dev/null +++ b/include/asm-m68k/machdep.h @@ -0,0 +1,45 @@ +#ifndef _M68K_MACHDEP_H +#define _M68K_MACHDEP_H + +struct pt_regs; +struct kbd_repeat; +struct mktime; +struct hwclk_time; +struct gendisk; +struct buffer_head; + +extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)); +/* machine dependent keyboard functions */ +extern int (*mach_keyb_init) (void); +extern int (*mach_kbdrate) (struct kbd_repeat *); +extern void (*mach_kbd_leds) (unsigned int); +/* machine dependent irq functions */ +extern void (*mach_init_IRQ) (void); +extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); +extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); +extern int (*mach_free_irq) (unsigned int irq, void *dev_id); +extern void (*mach_enable_irq) (unsigned int irq); +extern void (*mach_disable_irq) (unsigned int irq); +extern int (*mach_get_irq_list) (char *buf); +extern void (*mach_process_int) (int irq, struct pt_regs *fp); +/* machine dependent timer functions */ +extern unsigned long (*mach_gettimeoffset)(void); +extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour, + int *min, int *sec); +extern int (*mach_hwclk)(int, struct hwclk_time*); +extern int (*mach_set_clock_mmss)(unsigned long); +extern void (*mach_mksound)( unsigned int count, unsigned int ticks ); +extern void (*mach_reset)( void ); +extern int (*mach_floppy_init) (void); +extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); +extern void (*mach_hd_setup)(char *, int *); +extern void (*waitbut)(void); +extern struct fb_info *(*mach_fb_init)(long *); +extern long mach_max_dma_address; +extern void (*mach_debug_init)(void); +extern void (*mach_video_setup)(char *, int *); +extern void (*mach_floppy_setup)(char *, int *); +extern void (*mach_floppy_eject)(void); + +#endif /* _M68K_MACHDEP_H */ diff --git a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h new file mode 100644 index 000000000..cbee6c998 --- /dev/null +++ b/include/asm-m68k/mman.h @@ -0,0 +1,32 @@ +#ifndef __M68K_MMAN_H__ +#define __M68K_MMAN_H__ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x0 /* page can not be accessed */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __M68K_MMAN_H__ */ diff --git a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h new file mode 100644 index 000000000..c5def1604 --- /dev/null +++ b/include/asm-m68k/mmu_context.h @@ -0,0 +1,9 @@ +#ifndef __68K_MMU_CONTEXT_H +#define __68K_MMU_CONTEXT_H + +/* + * get a new mmu context.. do we need this on the m68k? + */ +#define get_mmu_context(x) do { } while (0) + +#endif diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h new file mode 100644 index 000000000..82dbe59c3 --- /dev/null +++ b/include/asm-m68k/page.h @@ -0,0 +1,67 @@ +#ifndef _M68K_PAGE_H +#define _M68K_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#define STRICT_MM_TYPECHECKS + +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + +#ifdef STRICT_MM_TYPECHECKS +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd[16]; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* + * .. while these make it easier on the compiler + */ +typedef unsigned long pte_t; +typedef struct { unsigned long pmd[16]; } pmd_t; +typedef unsigned long pgd_t; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) (x) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) (x) +#define __pgprot(x) (x) + +#endif + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* This handles the memory map.. */ +#define PAGE_OFFSET 0 +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) +#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) + +#endif /* __KERNEL__ */ + +#endif /* _M68K_PAGE_H */ diff --git a/include/asm-m68k/param.h b/include/asm-m68k/param.h new file mode 100644 index 000000000..475002cef --- /dev/null +++ b/include/asm-m68k/param.h @@ -0,0 +1,20 @@ +#ifndef _M68K_PARAM_H +#define _M68K_PARAM_H + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NGROUPS +#define NGROUPS 32 +#endif + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _M68K_PARAM_H */ diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h new file mode 100644 index 000000000..429a68938 --- /dev/null +++ b/include/asm-m68k/pgtable.h @@ -0,0 +1,741 @@ +#ifndef _M68K_PGTABLE_H +#define _M68K_PGTABLE_H + +#include<asm/setup.h> + +#ifndef __ASSEMBLY__ + +/* + * This file contains the functions and defines necessary to modify and use + * the m68k page table tree. + */ + +/* + * flush all atc entries (user-space entries only for the 680[46]0). + */ +static inline void __flush_tlb(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".word 0xf510\n"::); /* pflushan */ + else + __asm__ __volatile__("pflusha\n"::); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + if (CPU_IS_040_OR_060) { + register unsigned long a0 __asm__ ("a0") = addr; + __asm__ __volatile__(".word 0xf508" /* pflush (%a0) */ + : : "a" (a0)); + } else + __asm__ __volatile__("pflush #0,#0,(%0)" : : "a" (addr)); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".word 0xf518\n"::); /* pflusha */ + else + __asm__ __volatile__("pflusha\n"::); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long addr) +{ + if (vma->vm_mm == current->mm) + __flush_tlb_one(addr); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (mm == current->mm) + __flush_tlb(); +} + +/* 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) do{ \ + ((*(pteptr)) = (pteval)); \ + if (CPU_IS_060) \ + __asm__ __volatile__(".word 0xf518\n"::); /* pflusha */ \ + } while(0) + + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#define PMD_SHIFT 22 +#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 25 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: the m68k is configured as three-level, + * so we do have PMD level physically. + */ +#define PTRS_PER_PTE 1024 +#define PTRS_PER_PMD 8 +#define PTRS_PER_PGD 128 + +/* the no. of pointers that fit on a page: this will go away */ +#define PTRS_PER_PAGE (PAGE_SIZE/sizeof(void*)) + +typedef pgd_t pgd_table[PTRS_PER_PGD]; +typedef pmd_t pmd_table[PTRS_PER_PMD]; +typedef pte_t pte_table[PTRS_PER_PTE]; + +#define PGD_TABLES_PER_PAGE (PAGE_SIZE/sizeof(pgd_table)) +#define PMD_TABLES_PER_PAGE (PAGE_SIZE/sizeof(pmd_table)) +#define PTE_TABLES_PER_PAGE (PAGE_SIZE/sizeof(pte_table)) + +typedef pgd_table pgd_tablepage[PGD_TABLES_PER_PAGE]; +typedef pmd_table pmd_tablepage[PMD_TABLES_PER_PAGE]; +typedef pte_table pte_tablepage[PTE_TABLES_PER_PAGE]; + +/* 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_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +#endif /* __ASSEMBLY__ */ + +/* + * Definitions for MMU descriptors + */ +#define _PAGE_PRESENT 0x001 +#define _PAGE_SHORT 0x002 +#define _PAGE_RONLY 0x004 +#define _PAGE_ACCESSED 0x008 +#define _PAGE_DIRTY 0x010 +#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ +#define _PAGE_COW 0x800 /* implemented in software */ +#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */ +#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ +#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ +#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ +#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ + +#define _DESCTYPE_MASK 0x003 + +#define _CACHEMASK040 (~0x060) +#define _TABLE_MASK (0xfffffe00) + +#define _PAGE_TABLE (_PAGE_SHORT) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE) + +#ifndef __ASSEMBLY__ + +/* This is the cache mode to be used for pages containing page descriptors for + * processors >= '040. It is in pte_mknocache(), and the variable is defined + * and initialized in head.S */ +extern int m68k_pgtable_cachemode; + +#if defined(CONFIG_M68040_OR_M68060_ONLY) +#define mm_cachebits _PAGE_CACHE040 +#elif defined(CONFIG_M68020_OR_M68030_ONLY) +#define mm_cachebits 0 +#else +extern unsigned long mm_cachebits; +#endif + +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits) + +/* Alternate definitions that are compile time constants, for + initializing protection_map. The cachebits are fixed later. */ +#define PAGE_NONE_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) +#define PAGE_SHARED_C __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) +#define PAGE_COPY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) +#define PAGE_READONLY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) + +/* + * The m68k 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_C +#define __P001 PAGE_READONLY_C +#define __P010 PAGE_COPY_C +#define __P011 PAGE_COPY_C +#define __P100 PAGE_READONLY_C +#define __P101 PAGE_READONLY_C +#define __P110 PAGE_COPY_C +#define __P111 PAGE_COPY_C + +#define __S000 PAGE_NONE_C +#define __S001 PAGE_READONLY_C +#define __S010 PAGE_SHARED_C +#define __S011 PAGE_SHARED_C +#define __S100 PAGE_READONLY_C +#define __S101 PAGE_READONLY_C +#define __S110 PAGE_SHARED_C +#define __S111 PAGE_SHARED_C + +/* zero page used for uninitialized stuff */ +extern unsigned long empty_zero_page; + +/* + * BAD_PAGETABLE is used when we need a bogus page-table, while + * 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 pte_t * __bad_pagetable(void); + +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE empty_zero_page + +/* number of bits that fit into a memory pointer */ +#define BITS_PER_PTR (8*sizeof(unsigned long)) + +/* to align the pointer to a pointer address */ +#define PTR_MASK (~(sizeof(void*)-1)) + +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ +/* 64-bit machines, beware! SRB. */ +#define SIZEOF_PTR_LOG2 2 + +/* to find an entry in a page-table */ +#define PAGE_PTR(address) \ +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) + +/* For virtual address to physical address conversion */ +extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const)); +extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); +#define VTOP(addr) (mm_vtop((unsigned long)(addr))) +#define PTOV(addr) (mm_ptov((unsigned long)(addr))) + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +#define mk_pte(page, pgprot) \ +({ pte_t __pte; pte_val(__pte) = VTOP(page) + pgprot_val(pgprot); __pte; }) +#define mk_pte_phys(physpage, pgprot) \ +({ pte_t __pte; pte_val(__pte) = VTOP(physpage) + pgprot_val(pgprot); __pte; }) + +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } + +extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) +{ + int i; + + ptep = (pte_t *) VTOP(ptep); + for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16) + pmdp->pmd[i] = _PAGE_TABLE | _PAGE_ACCESSED | (unsigned long)ptep; +} + +/* early termination version of the above */ +extern inline void pmd_set_et(pmd_t * pmdp, pte_t * ptep) +{ + int i; + + ptep = (pte_t *) VTOP(ptep); + for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16) + pmdp->pmd[i] = _PAGE_PRESENT | _PAGE_ACCESSED | (unsigned long)ptep; +} + +extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) +{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | VTOP(pmdp); } + +extern inline unsigned long pte_page(pte_t pte) +{ return PTOV(pte_val(pte) & PAGE_MASK); } + +extern inline unsigned long pmd_page2(pmd_t *pmd) +{ return PTOV(pmd_val(*pmd) & _TABLE_MASK); } +#define pmd_page(pmd) pmd_page2(&(pmd)) + +extern inline unsigned long pgd_page(pgd_t pgd) +{ return PTOV(pgd_val(pgd) & _TABLE_MASK); } + +extern inline int pte_none(pte_t pte) { return !pte_val(pte); } +extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } +extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } + +extern inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); } +#define pmd_none(pmd) pmd_none2(&(pmd)) +extern inline int pmd_bad2(pmd_t *pmd) { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE; } +#define pmd_bad(pmd) pmd_bad2(&(pmd)) +extern inline int pmd_present2(pmd_t *pmd) { return pmd_val(*pmd) & _PAGE_TABLE; } +#define pmd_present(pmd) pmd_present2(&(pmd)) +extern inline void pmd_clear(pmd_t * pmdp) +{ + short i; + + for (i = 15; i >= 0; i--) + pmdp->pmd[i] = 0; +} + +extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); } +extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE; } +extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_TABLE; } + +extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; } + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +extern inline int pte_read(pte_t pte) { return 1; } +extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); } +extern inline int pte_exec(pte_t pte) { return 1; } +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; } + +extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } +extern inline pte_t pte_rdprotect(pte_t pte) { return pte; } +extern inline pte_t pte_exprotect(pte_t pte) { 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_RONLY; return pte; } +extern inline pte_t pte_mkread(pte_t pte) { return pte; } +extern inline pte_t pte_mkexec(pte_t pte) { 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; } +extern inline pte_t pte_mknocache(pte_t pte) +{ + pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode; + return pte; +} +extern inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | _PAGE_CACHE040; return pte; } + +/* to set the page-dir */ +extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir) +{ + tsk->tss.crp[0] = 0x80000000 | _PAGE_TABLE; + tsk->tss.crp[1] = VTOP(pgdir); + if (tsk == current) { + if (CPU_IS_040_OR_060) + __asm__ __volatile__ ("movel %0@,%/d0\n\t" + ".long 0x4e7b0806\n\t" + /* movec d0,urp */ + : : "a" (&tsk->tss.crp[1]) + : "d0"); + else + __asm__ __volatile__ ("movec %/cacr,%/d0\n\t" + "oriw #0x0808,%/d0\n\t" + "movec %/d0,%/cacr\n\t" + "pmove %0@,%/crp\n\t" + : : "a" (&tsk->tss.crp[0]) + : "d0"); + } +} + +#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) + +/* 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); +} + +extern pgd_t swapper_pg_dir[128]; +extern pgd_t kernel_pg_dir[128]; + +extern inline pgd_t * pgd_offset_k(unsigned long address) +{ + return kernel_pg_dir + (address >> PGDIR_SHIFT); +} + + +/* Find an entry in the second-level page table.. */ +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); +} + +/* Find an entry in the third-level page table.. */ +extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address) +{ + return (pte_t *) pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + +/* + * 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 nocache_page (unsigned long vaddr) +{ + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + if(CPU_IS_060) + __asm__ __volatile__ ("movel %0,%/a0\n\t" + ".word 0xf470" + : : "g" (VTOP(vaddr)) + : "a0"); + + dir = pgd_offset_k(vaddr); + pmdp = pmd_offset(dir,vaddr); + ptep = pte_offset(pmdp,vaddr); + *ptep = pte_mknocache(*ptep); + } +} + +static inline void cache_page (unsigned long vaddr) +{ + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + dir = pgd_offset_k(vaddr); + pmdp = pmd_offset(dir,vaddr); + ptep = pte_offset(pmdp,vaddr); + *ptep = pte_mkcache(*ptep); + } +} + + +extern const char PgtabStr_bad_pmd[]; +extern const char PgtabStr_bad_pgd[]; +extern const char PgtabStr_bad_pmdk[]; +extern const char PgtabStr_bad_pgdk[]; + +extern inline void pte_free(pte_t * pte) +{ + cache_page((unsigned long)pte); + free_page((unsigned long) pte); +} + +extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t * page = (pte_t *)__get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + memset((void *) page, 0, PAGE_SIZE); + nocache_page((unsigned long)page); + pmd_set(pmd,page); + return page + address; + } + pmd_set(pmd, BAD_PAGETABLE); + return NULL; + } + free_page((unsigned long)page); + } + if (pmd_bad(*pmd)) { + printk(PgtabStr_bad_pmd, pmd_val(*pmd)); + pmd_set(pmd, BAD_PAGETABLE); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +extern pmd_t *get_pointer_table (void); +extern void free_pointer_table (pmd_t *); +extern pmd_t *get_kpointer_table (void); +extern void free_kpointer_table (pmd_t *); + +extern inline void pmd_free(pmd_t * pmd) +{ + free_pointer_table (pmd); +} + +extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) +{ + address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + if (pgd_none(*pgd)) { + pmd_t *page = get_pointer_table(); + if (pgd_none(*pgd)) { + if (page) { + pgd_set(pgd, page); + return page + address; + } + pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); + return NULL; + } + free_pointer_table(page); + } + if (pgd_bad(*pgd)) { + printk(PgtabStr_bad_pgd, pgd_val(*pgd)); + pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); + return NULL; + } + return (pmd_t *) pgd_page(*pgd) + address; +} + +extern inline void pte_free_kernel(pte_t * pte) +{ + cache_page((unsigned long)pte); + free_page((unsigned long) pte); +} + +extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + if (pmd_none(*pmd)) { + pte_t * page = (pte_t *) get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + nocache_page((unsigned long)page); + pmd_set(pmd, page); + return page + address; + } + pmd_set(pmd, BAD_PAGETABLE); + return NULL; + } + free_page((unsigned long) page); + } + if (pmd_bad(*pmd)) { + printk(PgtabStr_bad_pmdk, pmd_val(*pmd)); + pmd_set(pmd, BAD_PAGETABLE); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} + +extern inline void pmd_free_kernel(pmd_t * pmd) +{ + free_kpointer_table(pmd); +} + +extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address) +{ + address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + if (pgd_none(*pgd)) { + pmd_t *page = get_kpointer_table(); + if (pgd_none(*pgd)) { + if (page) { + pgd_set(pgd, page); + return page + address; + } + pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); + return NULL; + } + free_kpointer_table(page); + } + if (pgd_bad(*pgd)) { + printk(PgtabStr_bad_pgdk, pgd_val(*pgd)); + pgd_set(pgd, (pmd_t *)BAD_PAGETABLE); + return NULL; + } + return (pmd_t *) pgd_page(*pgd) + address; +} + +extern inline void pgd_free(pgd_t * pgd) +{ + free_pointer_table ((pmd_t *) pgd); +} + +extern inline pgd_t * pgd_alloc(void) +{ + return (pgd_t *)get_pointer_table (); +} + +#define flush_icache() \ +do { \ + if (CPU_IS_040_OR_060) \ + asm __volatile__ ("nop; .word 0xf498 /* cinva %%ic */"); \ + else \ + asm __volatile__ ("movec %/cacr,%/d0;" \ + "oriw %0,%/d0;" \ + "movec %/d0,%/cacr" \ + : /* no outputs */ \ + : "i" (FLUSH_I) \ + : "d0"); \ +} while (0) + +/* + * invalidate the cache for the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_clear (unsigned long paddr, int len); +/* + * push any dirty cache in the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_push (unsigned long paddr, int len); + +/* + * push and invalidate pages in the specified user virtual + * memory range. + */ +extern void cache_push_v (unsigned long vaddr, int len); + +/* cache code */ +#define FLUSH_I_AND_D (0x00000808) +#define FLUSH_I (0x00000008) + +/* This is needed whenever the virtual mapping of the current + process changes. */ +#define __flush_cache_all() \ + do { \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__ ("nop; .word 0xf478\n" ::); \ + else \ + __asm__ __volatile__ ("movec %%cacr,%%d0\n\t" \ + "orw %0,%%d0\n\t" \ + "movec %%d0,%%cacr" \ + : : "di" (FLUSH_I_AND_D) : "d0"); \ + } while (0) + +#define __flush_cache_030() \ + do { \ + if (CPU_IS_020_OR_030) \ + __asm__ __volatile__ ("movec %%cacr,%%d0\n\t" \ + "orw %0,%%d0\n\t" \ + "movec %%d0,%%cacr" \ + : : "di" (FLUSH_I_AND_D) : "d0"); \ + } while (0) + +#define flush_cache_all() __flush_cache_all() + +extern inline void flush_cache_mm(struct mm_struct *mm) +{ +#if FLUSH_VIRTUAL_CACHE_040 + if (mm == current->mm) __flush_cache_all(); +#else + if (mm == current->mm) __flush_cache_030(); +#endif +} + +extern inline void flush_cache_range(struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + if (mm == current->mm){ +#if FLUSH_VIRTUAL_CACHE_040 + if (CPU_IS_040_OR_060) + cache_push_v(start, end-start); + else +#endif + __flush_cache_030(); + } +} + +extern inline void flush_cache_page(struct vm_area_struct *vma, + unsigned long vmaddr) +{ + if (vma->vm_mm == current->mm){ +#if FLUSH_VIRTUAL_CACHE_040 + if (CPU_IS_040_OR_060) + cache_push_v(vmaddr, PAGE_SIZE); + else +#endif + __flush_cache_030(); + } +} + +/* Push the page at kernel virtual address and clear the icache */ +extern inline void flush_page_to_ram (unsigned long address) +{ + if (CPU_IS_040_OR_060) { + register unsigned long tmp __asm ("a0") = VTOP(address); + __asm__ __volatile__ ("nop\n\t" + ".word 0xf470 /* cpushp %%dc,(%0) */\n\t" + ".word 0xf490 /* cinvp %%ic,(%0) */" + : : "a" (tmp)); + } + else + __asm volatile ("movec %%cacr,%%d0\n\t" + "orw %0,%%d0\n\t" + "movec %%d0,%%cacr" + : : "di" (FLUSH_I) : "d0"); +} + +/* Push n pages at kernel virtual address and clear the icache */ +extern inline void flush_pages_to_ram (unsigned long address, int n) +{ + if (CPU_IS_040_OR_060) { + while (n--) { + register unsigned long tmp __asm ("a0") = VTOP(address); + __asm__ __volatile__ ("nop\n\t" + ".word 0xf470 /* cpushp %%dc,(%0) */\n\t" + ".word 0xf490 /* cinvp %%ic,(%0) */" + : : "a" (tmp)); + address += PAGE_SIZE; + } + } + else + __asm volatile ("movec %%cacr,%%d0\n\t" + "orw %0,%%d0\n\t" + "movec %%d0,%%cacr" + : : "di" (FLUSH_I) : "d0"); +} + +/* + * Check if the addr/len goes up to the end of a physical + * memory chunk. Used for DMA functions. + */ +int mm_end_of_chunk (unsigned long addr, int len); + +/* + * Map some physical address range into the kernel address space. The + * code is copied and adapted from map_chunk(). + */ +extern unsigned long kernel_map(unsigned long paddr, unsigned long size, + int nocacheflag, unsigned long *memavailp ); +/* + * Change the cache mode of some kernel address range. + */ +extern void kernel_set_cachemode( unsigned long address, unsigned long size, + unsigned cmode ); + +/* Values for nocacheflag and cmode */ +#define KERNELMAP_FULL_CACHING 0 +#define KERNELMAP_NOCACHE_SER 1 +#define KERNELMAP_NOCACHE_NONSER 2 +#define KERNELMAP_NO_COPYBACK 3 + +/* + * The m68k 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) +{ +} + +/* + * I don't know what is going on here, but since these were changed, + * swapping hasn't been working on the 68040. + */ + +#define SWP_TYPE(entry) (((entry) >> 2) & 0x7f) +#if 0 +#define SWP_OFFSET(entry) ((entry) >> 9) +#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9)) +#else +#define SWP_OFFSET(entry) ((entry) >> PAGE_SHIFT) +#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << PAGE_SHIFT)) +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* _M68K_PGTABLE_H */ diff --git a/include/asm-m68k/posix_types.h b/include/asm-m68k/posix_types.h new file mode 100644 index 000000000..535095971 --- /dev/null +++ b/include/asm-m68k/posix_types.h @@ -0,0 +1,51 @@ +#ifndef __ARCH_M68K_POSIX_TYPES_H +#define __ARCH_M68K_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_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_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; + +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) + +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) + +#undef __FD_ISSET +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h new file mode 100644 index 000000000..d228816af --- /dev/null +++ b/include/asm-m68k/processor.h @@ -0,0 +1,92 @@ +/* + * include/asm-m68k/processor.h + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#ifndef __ASM_M68K_PROCESSOR_H +#define __ASM_M68K_PROCESSOR_H + +#include <asm/segment.h> + +/* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#define TASK_SIZE (0xF0000000UL) + +/* + * Bus types + */ +#define EISA_bus 0 +#define MCA_bus 0 + +/* MAX floating point unit state size (FSAVE/FRESTORE) */ +#define FPSTATESIZE (216/sizeof(unsigned char)) + +/* + * if you change this structure, you must change the code and offsets + * in m68k/machasm.S + */ + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short sr; /* saved status register */ + unsigned short fs; /* saved fs (sfc, dfc) */ + unsigned long crp[2]; /* cpu root pointer */ + unsigned long esp0; /* points to SR of stack frame */ + unsigned long fp[8*3]; + unsigned long fpcntl[3]; /* fp control regs */ + unsigned char fpstate[FPSTATESIZE]; /* floating point state */ +}; + +#define INIT_MMAP { &init_mm, 0, 0x40000000, __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED), VM_READ | VM_WRITE | VM_EXEC } + +#define INIT_TSS { \ + sizeof(init_kernel_stack) + (long) init_kernel_stack, 0, \ + PS_S, KERNEL_DS, \ + {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \ +} + +#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) +#define free_kernel_stack(page) free_page((page)) + +/* + * Do necessary setup to start up a newly executed thread. + */ +static inline void start_thread(struct pt_regs * regs, unsigned long pc, + unsigned long usp) +{ + unsigned long nilstate = 0; + + /* clear floating point state */ + __asm__ __volatile__ ("frestore %0@" : : "a" (&nilstate)); + + /* reads from user space */ + set_fs(USER_DS); + + regs->pc = pc; + regs->sr &= ~0x2000; + wrusp(usp); +} + +/* + * Return saved PC of a blocked thread. + */ +extern inline unsigned long thread_saved_pc(struct thread_struct *t) +{ + return ((unsigned long *)((struct switch_stack *)t->ksp)->a6)[1]; +} + +/* + * Return_address is a replacement for __builtin_return_address(count) + * which on certain architectures cannot reasonably be implemented in GCC + * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * Note that __builtin_return_address(x>=1) is forbidden because the GCC + * aborts compilation on some CPUs. It's simply not possible to unwind + * some CPU's stackframes. + */ +#define return_address() __builtin_return_address(0) + +#endif diff --git a/include/asm-m68k/ptrace.h b/include/asm-m68k/ptrace.h new file mode 100644 index 000000000..449b7bd8e --- /dev/null +++ b/include/asm-m68k/ptrace.h @@ -0,0 +1,73 @@ +#ifndef _M68K_PTRACE_H +#define _M68K_PTRACE_H + +#define PT_D1 0 +#define PT_D2 1 +#define PT_D3 2 +#define PT_D4 3 +#define PT_D5 4 +#define PT_D6 5 +#define PT_D7 6 +#define PT_A0 7 +#define PT_A1 8 +#define PT_A2 9 +#define PT_A3 10 +#define PT_A4 11 +#define PT_A5 12 +#define PT_A6 13 +#define PT_D0 14 +#define PT_USP 15 +#define PT_ORIG_D0 16 +#define PT_SR 17 +#define PT_PC 18 + +#ifndef __ASSEMBLY__ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long d1; + long d2; + long d3; + long d4; + long d5; + long a0; + long a1; + long d0; + long orig_d0; + long stkadj; + unsigned short sr; + unsigned long pc; + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ +}; + +/* + * This is the extended stack used by signal handlers and the context + * switcher: it's pushed after the normal "struct pt_regs". + */ +struct switch_stack { + unsigned long d6; + unsigned long d7; + unsigned long a2; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long retpc; +}; + +#ifdef __KERNEL__ + +#ifndef PS_S +#define PS_S (0x2000) +#define PS_M (0x1000) +#endif + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _M68K_PTRACE_H */ diff --git a/include/asm-m68k/resource.h b/include/asm-m68k/resource.h new file mode 100644 index 000000000..f94ce2708 --- /dev/null +++ b/include/asm-m68k/resource.h @@ -0,0 +1,39 @@ +#ifndef _M68K_RESOURCE_H +#define _M68K_RESOURCE_H + +/* + * Resource limits + */ + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_RSS 5 /* max resident set size */ +#define RLIMIT_NPROC 6 /* max number of processes */ +#define RLIMIT_NOFILE 7 /* max number of open files */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space*/ +#define RLIMIT_AS 9 /* address space limit */ + +#define RLIM_NLIMITS 10 + +#ifdef __KERNEL__ + +#define INIT_RLIMITS \ +{ \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {_STK_LIM, _STK_LIM}, \ + { 0, LONG_MAX}, \ + {LONG_MAX, LONG_MAX}, \ + {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, \ + {NR_OPEN, NR_OPEN}, \ + {LONG_MAX, LONG_MAX}, \ + {LONG_MAX, LONG_MAX} \ +} + +#endif /* __KERNEL__ */ + +#endif /* _M68K_RESOURCE_H */ diff --git a/include/asm-m68k/segment.h b/include/asm-m68k/segment.h index 89079be3f..5fe0c033f 100644 --- a/include/asm-m68k/segment.h +++ b/include/asm-m68k/segment.h @@ -1,208 +1,21 @@ -/* - * linux/include/asm-m68k/segment.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive - * for more details. - */ - -/* - * 680x0 support added by Hamish Macdonald - */ - #ifndef _M68K_SEGMENT_H #define _M68K_SEGMENT_H -static inline unsigned char get_user_byte(const char * addr) -{ - register unsigned char _v; - - __asm__ __volatile__ ("movesb %1,%0":"=r" (_v):"m" (*addr)); - return _v; -} - -#define get_fs_byte(addr) get_user_byte((char *)(addr)) - -static inline unsigned short get_user_word(const short *addr) -{ - unsigned short _v; - - __asm__ __volatile__ ("movesw %1,%0":"=r" (_v):"m" (*addr)); - return _v; -} - -#define get_fs_word(addr) get_user_word((short *)(addr)) - -static inline unsigned long get_user_long(const int *addr) -{ - unsigned long _v; - - __asm__ __volatile__ ("movesl %1,%0":"=r" (_v):"m" (*addr)); \ - return _v; -} - -#define get_fs_long(addr) get_user_long((int *)(addr)) - -static inline void put_user_byte(char val,char *addr) -{ - __asm__ __volatile__ ("movesb %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory"); -} - -#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) - -static inline void put_user_word(short val,short * addr) -{ - __asm__ __volatile__ ("movesw %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory"); -} - -#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) - -static inline void put_user_long(unsigned long val,int * addr) -{ - __asm__ __volatile__ ("movesl %0,%1": /* no outputs */ :"r" (val),"m" (*addr) : "memory"); -} - -#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) - -static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - if (n == 0) return; - __asm__ __volatile__ ("1:\n\t" - "moveb %1@+,d0\n\t" - "movesb d0,%2@+\n\t" - "dbra %0,1b\n\t" - "clrw %0\n\t" - "subql #1,%0\n\t" - "bccs 1b" - : "=d" (n), "=a" (from), "=a" (to) - : "1" (from), "2" (to), "0" (n-1) - : "d0", "memory"); -} - -static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - if (n == 0) { - return; - } else if (n == 1) { - put_user_byte(*(const char *) from, (char *) to); - return; - } else if (n == 2) { - put_user_word(*(const short *) from, (short *) to); - return; - } else if (n == 3) { - put_user_word(*(const short *) from, (short *) to); - put_user_byte(*(2+(const char *) from), 2+(char *) to); - return; - } else if (n == 4) { - put_user_long(*(const int *) from, (int *) to); - return; - } -#if 0 -#define COMMON(x) \ -__asm__("cld\n\t" \ - "push %%es\n\t" \ - "push %%fs\n\t" \ - "pop %%es\n\t" \ - "rep ; movsl\n\t" \ - x \ - "pop %%es" \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("movsb\n\t"); - return; - case 2: - COMMON("movsw\n\t"); - return; - case 3: - COMMON("movsw\n\tmovsb\n\t"); - return; - } -#undef COMMON -#else - __generic_memcpy_tofs(to,from,n); +/* define constants */ +/* Address spaces (FC0-FC2) */ +#define USER_DATA (1) +#ifndef USER_DS +#define USER_DS (USER_DATA) #endif -} - -static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - if (n == 0) return; - __asm__ __volatile__ ("1:\n\t" - "movesb %1@+,d0\n\t" - "moveb d0,%2@+\n\t" - "dbra %0,1b\n\t" - "clrw %0\n\t" - "subql #1,%0\n\t" - "bccs 1b" - : "=d" (n), "=a" (from), "=a" (to) - : "1" (from), "2" (to), "0" (n-1) - : "d0", "memory"); -} - -static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - if (n == 0) { - return; - } else if (n == 1) { - *(char *)to = get_user_byte((const char *) from); - return; - } else if (n == 2) { - *(short *)to = get_user_word((const short *) from); - return; - } else if (n == 3) { - *(short *) to = get_user_word((const short *) from); - *(2+(char *) to) = get_user_byte(2+(const char *) from); - return; - } else if (n == 4) { - *(int *) to = get_user_long((const int *) from); - return; - } -#if 0 -#define COMMON(x) \ -__asm__("cld\n\t" \ - "rep ; fs ; movsl\n\t" \ - x \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si","memory") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("fs ; movsb"); - return; - case 2: - COMMON("fs ; movsw"); - return; - case 3: - COMMON("fs ; movsw\n\tfs ; movsb"); - return; - } -#undef COMMON -#else - __generic_memcpy_fromfs(to,from,n); +#define USER_PROGRAM (2) +#define SUPER_DATA (5) +#ifndef KERNEL_DS +#define KERNEL_DS (SUPER_DATA) #endif -} +#define SUPER_PROGRAM (6) +#define CPU_SPACE (7) -#define memcpy_fromfs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_fromfs((to),(from),(n)) : \ - __generic_memcpy_fromfs((to),(from),(n))) - -#define memcpy_tofs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_tofs((to),(from),(n)) : \ - __generic_memcpy_tofs((to),(from),(n))) +#ifndef __ASSEMBLY__ /* * Get/set the SFC/DFC registers for MOVES instructions @@ -211,7 +24,7 @@ __asm__("cld\n\t" \ static inline unsigned long get_fs(void) { unsigned long _v; - __asm__ ("movec dfc,%0":"=r" (_v):); + __asm__ ("movec %/dfc,%0":"=r" (_v):); return _v; } @@ -219,23 +32,16 @@ static inline unsigned long get_fs(void) static inline unsigned long get_ds(void) { /* return the supervisor data space code */ - return 0x5; + return KERNEL_DS; } static inline void set_fs(unsigned long val) { - __asm__ __volatile__ ("movec %0,sfc\n\t" - "movec %0,dfc\n\t" - : /* no outputs */ : "r" (val), "r" (val) : "memory"); + __asm__ __volatile__ ("movec %0,%/sfc\n\t" + "movec %0,%/dfc\n\t" + : /* no outputs */ : "r" (val) : "memory"); } -/* define constants */ -/* Address spaces (FC0-FC2) */ -#ifndef USER_DS -#define USER_DS (1) -#endif -#ifndef KERNEL_DS -#define KERNEL_DS (5) -#endif +#endif /* __ASSEMBLY__ */ #endif /* _M68K_SEGMENT_H */ diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h new file mode 100644 index 000000000..ef23201c3 --- /dev/null +++ b/include/asm-m68k/semaphore.h @@ -0,0 +1,68 @@ +#ifndef _M68K_SEMAPHORE_H +#define _M68K_SEMAPHORE_H + +#include <linux/linkage.h> + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + * + * m68k version by Andreas Schwab + */ + +struct semaphore { + int count; + int waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage void __up_wakeup(void /* special register calling convention */); + +extern void __down(struct semaphore * sem); +extern void __up(struct semaphore * sem); + +/* + * This is ugly, but we want the default case to fall through. + * "down_failed" is a special asm handler that calls the C + * routine that actually waits. See arch/m68k/lib/semaphore.S + */ +extern inline void down(struct semaphore * sem) +{ + register struct semaphore *sem1 __asm__ ("%a1") = sem; + __asm__ __volatile__( + "| atomic down operation\n\t" + "lea %%pc@(1f),%%a0\n\t" + "subql #1,%0\n\t" + "jmi " SYMBOL_NAME_STR(__down_failed) "\n" + "1:" + : /* no outputs */ + : "m" (sem->count), "a" (sem1) + : "%a0", "memory"); +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +extern inline void up(struct semaphore * sem) +{ + register struct semaphore *sem1 __asm__ ("%a1") = sem; + __asm__ __volatile__( + "| atomic up operation\n\t" + "lea %%pc@(1f),%%a0\n\t" + "addql #1,%0\n\t" + "jle " SYMBOL_NAME_STR(__up_wakeup) "\n" + "1:" + : /* no outputs */ + : "m" (sem->count), "a" (sem1) + : "%a0", "memory"); +} + +#endif diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h new file mode 100644 index 000000000..fecf48e55 --- /dev/null +++ b/include/asm-m68k/serial.h @@ -0,0 +1,380 @@ +/* + * include/linux/serial.h + * + * Copyright (C) 1992 by Theodore Ts'o. + * + * Redistribution of this file is permitted under the terms of the GNU + * Public License (GPL) + */ + +#ifndef _M68K_SERIAL_H +#define _M68K_SERIAL_H + + +/* m68k serial port types are numbered from 100 to avoid interference + * with the PC types (1..4) + */ +#define PORT_UNKNOWN 0 +#define PORT_8250 1 +#define PORT_16450 2 +#define PORT_16550 3 +#define PORT_16550A 4 +#define PORT_CIRRUS 5 +#define SER_SCC_NORM 100 /* standard SCC channel */ +#define SER_SCC_DMA 101 /* SCC channel with DMA support */ +#define SER_MFP_CTRL 102 /* standard MFP port with modem control signals */ +#define SER_MFP_BARE 103 /* MFP port without modem controls */ +#define SER_MIDI 104 /* Atari MIDI */ +#define SER_AMIGA 105 /* Amiga built-in serial port */ +#define SER_IOEXT 106 /* Amiga GVP IO-Extender (16c552) */ +#define SER_MFC_III 107 /* Amiga BSC Multiface Card III (MC68681) */ + + +struct serial_struct { + int type; + int line; + int port; + int irq; + int flags; + int xmit_fifo_size; + int custom_divisor; + int baud_base; + unsigned short close_delay; + char reserved_char[2]; + int hub6; + unsigned short closing_wait; /* time to wait before closing */ + unsigned short closing_wait2; /* no longer used... */ + int reserved[4]; +}; + +/* + * For the close wait times, 0 means wait forever for serial port to + * flush its output. 65535 means don't wait at all. + */ +#define ASYNC_CLOSING_WAIT_INF 0 +#define ASYNC_CLOSING_WAIT_NONE 65535 + +/* This function tables does the abstraction from the underlying + * hardware: + * + * init(): Initialize the port as necessary, set RTS and DTR and + * enable interrupts. It does not need to set the speed and other + * parameters, because change_speed() is called, too. + * deinit(): Stop and shutdown the port (e.g. disable interrupts, ...) + * enab_tx_int(): Enable or disable the Tx Buffer Empty interrupt + * independently from other interrupt sources. If the int is + * enabled, the transmitter should also be restarted, i.e. if there + * are any chars to be sent, they should be put into the Tx + * register. The real en/disabling of the interrupt may be a no-op + * if there is no way to do this or it is too complex. This Tx ints + * are just disabled to save some interrupts if the transmitter is + * stopped anyway. But the restarting must be implemented! + * check_custom_divisor(): Check the given custom divisor for legality + * and return 0 if OK, non-zero otherwise. + * change_speed(): Set port speed, character size, number of stop + * bits and parity from the termios structure. If the user wants + * to set the speed with a custom divisor, he is required to + * check the baud_base first! + * throttle(): Set or clear the RTS line according to 'status'. + * set_break(): Set or clear the 'Send a Break' flag. + * get_serial_info(): Fill in the baud_base and custom_divisor + * fields of a serial_struct. It may also modify other fields, if + * needed. + * get_modem_info(): Return the status of RTS, DTR, DCD, RI, DSR and CTS. + * set_modem_info(): Set the status of RTS and DTR according to + * 'new_dtr' and 'new_rts', resp. 0 = clear, 1 = set, -1 = don't change + * ioctl(): Process any port-specific ioctl's. This pointer may be + * NULL, if the port has no own ioctl's. + * stop_receive(): Turn off the Rx part of the port, so no more characters + * will be received. This is called before shutting the port down. + * trans_empty(): Return !=0 if there are no more characters still to be + * sent out (Tx buffer register and FIFOs empty) + * check_open(): Is called before the port is opened. The driver can check + * if that's ok and return an error code, or keep track of the opening + * even before init() is called. Use deinit() for matching closing of the + * port. + * + */ + +struct async_struct; + +typedef struct { + void (*init)( struct async_struct *info ); + void (*deinit)( struct async_struct *info, int leave_dtr ); + void (*enab_tx_int)( struct async_struct *info, int enab_flag ); + int (*check_custom_divisor)( struct async_struct *info, int baud_base, + int divisor ); + void (*change_speed)( struct async_struct *info ); + void (*throttle)( struct async_struct *info, int status ); + void (*set_break)( struct async_struct *info, int break_flag ); + void (*get_serial_info)( struct async_struct *info, + struct serial_struct *retinfo ); + unsigned int (*get_modem_info)( struct async_struct *info ); + int (*set_modem_info)( struct async_struct *info, int new_dtr, + int new_rts ); + int (*ioctl)( struct tty_struct *tty, struct file *file, + struct async_struct *info, unsigned int cmd, + unsigned long arg ); + void (*stop_receive)( struct async_struct *info ); + int (*trans_empty)( struct async_struct *info ); + int (*check_open)( struct async_struct *info, struct tty_struct *tty, + struct file *file ); +} SERIALSWITCH; + +/* + * Definitions for async_struct (and serial_struct) flags field + */ +#define ASYNC_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes + on the callout port */ +#define ASYNC_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */ +#define ASYNC_SAK 0x0004 /* Secure Attention Key (Orange book) */ +#define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ + +#define ASYNC_SPD_MASK 0x0030 +#define ASYNC_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */ + +#define ASYNC_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */ +#define ASYNC_SPD_CUST 0x0030 /* Use user-specified divisor */ + +#define ASYNC_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */ +#define ASYNC_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */ +#define ASYNC_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */ +#define ASYNC_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ +#define ASYNC_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */ + +#define ASYNC_FLAGS 0x0FFF /* Possible legal async flags */ +#define ASYNC_USR_MASK 0x0430 /* Legal flags that non-privileged + * users can set or reset */ + +/* Internal flags used only by drivers/char/m68kserial.c */ +#define ASYNC_INITIALIZED 0x80000000 /* Serial port was initialized */ +#define ASYNC_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ +#define ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ +#define ASYNC_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */ +#define ASYNC_CLOSING 0x08000000 /* Serial port is closing */ +#define ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */ +#define ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */ + +/* + * Serial input interrupt line counters -- external structure + * Four lines can interrupt: CTS, DSR, RI, DCD + */ +struct serial_icounter_struct { + int cts, dsr, rng, dcd; + int reserved[16]; +}; + + +#ifdef __KERNEL__ +/* + * This is our internal structure for each serial port's state. + * + * Many fields are paralleled by the structure used by the serial_struct + * structure. + * + * For definitions of the flags field, see tty.h + */ + +#include <linux/termios.h> +#include <linux/tqueue.h> + +/* + * Counters of the input lines (CTS, DSR, RI, CD) interrupts + */ +struct async_icount { + __u32 cts, dsr, rng, dcd; +}; + +struct async_struct { + int magic; + int baud_base; + int port; + int irq; + int flags; /* defined in tty.h */ + int hub6; /* HUB6 plus one */ + int type; + struct tty_struct *tty; + int read_status_mask; + int ignore_status_mask; + int timeout; + int xmit_fifo_size; + int custom_divisor; + int x_char; /* xon/xoff character */ + int close_delay; + unsigned short closing_wait; + unsigned short closing_wait2; + int IER; /* Interrupt Enable Register */ + int MCR; /* Modem control register */ + int MCR_noint; /* MCR with interrupts off */ + unsigned long event; + unsigned long last_active; + int line; + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; + struct tq_struct tqueue; + struct tq_struct tqueue_hangup; + struct termios normal_termios; + struct termios callout_termios; + struct wait_queue *open_wait; + struct wait_queue *close_wait; + struct wait_queue *delta_msr_wait; + struct async_icount icount; /* kernel counters for the 4 input interrupts */ + struct async_struct *next_port; /* For the linked list */ + struct async_struct *prev_port; + void *board_base; /* board-base address for use with + boards carrying several UART's, + like some Amiga boards. */ + unsigned short nr_uarts; /* UART-counter, that indicates + how many UART's there are on + the board. If the board has a + IRQ-register, this can be used + to check if any of the uarts, + on the board has requested an + interrupt, instead of checking + IRQ-registers on all UART's */ + SERIALSWITCH *sw; /* functions to manage this port */ +}; + +#define SERIAL_MAGIC 0x5301 + +/* + * The size of the serial xmit buffer is 1 page, or 4096 bytes + */ +#define SERIAL_XMIT_SIZE 4096 + +/* + * Events are used to schedule things to happen at timer-interrupt + * time, instead of at rs interrupt time. + */ +#define RS_EVENT_WRITE_WAKEUP 0 + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* Export to allow PCMCIA to use this - Dave Hinds */ +extern int register_serial(struct serial_struct *req); +extern void unregister_serial(int line); +extern struct async_struct rs_table[]; +extern task_queue tq_serial; + + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static __inline__ void rs_sched_event(struct async_struct *info, int event) +{ + info->event |= 1 << event; + queue_task_irq(&info->tqueue, &tq_serial); + mark_bh(SERIAL_BH); +} + +static __inline__ void rs_receive_char( struct async_struct *info, + int ch, int err ) +{ + struct tty_struct *tty = info->tty; + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + return; + tty->flip.count++; + if (err == TTY_BREAK) { + if (info->flags & ASYNC_SAK) + do_SAK(tty); + } + *tty->flip.flag_buf_ptr++ = err; + *tty->flip.char_buf_ptr++ = ch; + queue_task_irq(&tty->flip.tqueue, &tq_timer); +} + +static __inline__ int rs_get_tx_char( struct async_struct *info ) +{ + unsigned char ch; + + if (info->x_char) { + ch = info->x_char; + info->x_char = 0; + return( ch ); + } + + if (info->xmit_cnt <= 0 || info->tty->stopped || info->tty->hw_stopped) + return( -1 ); + + ch = info->xmit_buf[info->xmit_tail++]; + info->xmit_tail &= SERIAL_XMIT_SIZE - 1; + if (--info->xmit_cnt < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + return( ch ); +} + +static __inline__ int rs_no_more_tx( struct async_struct *info ) +{ + return( info->xmit_cnt <= 0 || + info->tty->stopped || + info->tty->hw_stopped ); +} + +static __inline__ void rs_dcd_changed( struct async_struct *info, int dcd ) + +{ + /* update input line counter */ + info->icount.dcd++; + wake_up_interruptible(&info->delta_msr_wait); + + if (info->flags & ASYNC_CHECK_CD) { +#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) + printk("ttyS%d CD now %s...", info->line, + dcd ? "on" : "off"); +#endif + if (dcd) { + wake_up_interruptible(&info->open_wait); + } else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_CALLOUT_NOHUP))) { +#ifdef SERIAL_DEBUG_OPEN + printk("scheduling hangup..."); +#endif + queue_task_irq(&info->tqueue_hangup, + &tq_scheduler); + } + } +} + + +void rs_stop( struct tty_struct *tty ); +void rs_start( struct tty_struct *tty ); + +static __inline__ void rs_check_cts( struct async_struct *info, int cts ) +{ + /* update input line counter */ + info->icount.cts++; + wake_up_interruptible(&info->delta_msr_wait); + + if ((info->flags & ASYNC_CTS_FLOW) && info->tty) + if (info->tty->hw_stopped) { + if (cts) { +#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) + printk("CTS tx start..."); +#endif + info->tty->hw_stopped = 0; + rs_start( info->tty ); + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + return; + } + } else { + if (!cts) { + info->tty->hw_stopped = 1; + rs_stop( info->tty ); + } + } + +} + + +#endif /* __KERNEL__ */ + +#endif /* _M68K_SERIAL_H */ diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h new file mode 100644 index 000000000..96f91963b --- /dev/null +++ b/include/asm-m68k/setup.h @@ -0,0 +1,397 @@ +/* +** asm/setup.h -- Definition of the Linux/m68k boot information structure +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 09/29/92 by Greg Harp +** +** 5/2/94 Roman Hodek: +** Added bi_atari part of the machine dependent union bi_un; for now it +** contains just a model field to distinguish between TT and Falcon. +** 26/7/96 Roman Zippel: +** Renamed to setup.h; added some useful macros to allow gcc some +** optimizations if possible. +*/ + +#ifndef _M68K_SETUP_H +#define _M68K_SETUP_H + +#include <linux/config.h> +#include <asm/zorro.h> + +/* + * Amiga specific part of bootinfo structure. + */ + +#define NUM_AUTO 16 + +#ifndef __ASSEMBLY__ + +#define AMIGAHW_DECLARE(name) unsigned name : 1 +#define AMIGAHW_SET(name) (boot_info.bi_amiga.hw_present.name = 1) +#define AMIGAHW_PRESENT(name) (boot_info.bi_amiga.hw_present.name) + +struct bi_Amiga { + int model; /* Amiga Model (3000?) */ + int num_autocon; /* # of autoconfig devices found */ + struct ConfigDev autocon[NUM_AUTO]; /* up to 16 autoconfig devices */ +#ifdef HACKER_KERNEL + void (*exit_func)(void); /* addr of function to exit kernel */ + unsigned long chip_addr; /* start of chip memory (bytes) */ +#endif + unsigned long chip_size; /* size of chip memory (bytes) */ + unsigned char vblank; /* VBLANK frequency */ + unsigned char psfreq; /* power supply frequency */ + unsigned long eclock; /* EClock frequency */ + unsigned long chipset; /* native chipset present */ + struct { + /* video hardware */ + AMIGAHW_DECLARE(AMI_VIDEO); /* Amiga Video */ + AMIGAHW_DECLARE(AMI_BLITTER); /* Amiga Blitter */ + AMIGAHW_DECLARE(AMBER_FF); /* Amber Flicker Fixer */ + /* sound hardware */ + AMIGAHW_DECLARE(AMI_AUDIO); /* Amiga Audio */ + /* disk storage interfaces */ + AMIGAHW_DECLARE(AMI_FLOPPY); /* Amiga Floppy */ + AMIGAHW_DECLARE(A3000_SCSI); /* SCSI (wd33c93, A3000 alike) */ + AMIGAHW_DECLARE(A4000_SCSI); /* SCSI (ncr53c710, A4000T alike) */ + AMIGAHW_DECLARE(A1200_IDE); /* IDE (A1200 alike) */ + AMIGAHW_DECLARE(A4000_IDE); /* IDE (A4000 alike) */ + AMIGAHW_DECLARE(CD_ROM); /* CD ROM drive */ + /* other I/O hardware */ + AMIGAHW_DECLARE(AMI_KEYBOARD); /* Amiga Keyboard */ + AMIGAHW_DECLARE(AMI_MOUSE); /* Amiga Mouse */ + AMIGAHW_DECLARE(AMI_SERIAL); /* Amiga Serial */ + AMIGAHW_DECLARE(AMI_PARALLEL); /* Amiga Parallel */ + /* real time clocks */ + AMIGAHW_DECLARE(A2000_CLK); /* Hardware Clock (A2000 alike) */ + AMIGAHW_DECLARE(A3000_CLK); /* Hardware Clock (A3000 alike) */ + /* supporting hardware */ + AMIGAHW_DECLARE(CHIP_RAM); /* Chip RAM */ + AMIGAHW_DECLARE(PAULA); /* Paula (8364) */ + AMIGAHW_DECLARE(DENISE); /* Denise (8362) */ + AMIGAHW_DECLARE(DENISE_HR); /* Denise (8373) */ + AMIGAHW_DECLARE(LISA); /* Lisa (8375) */ + AMIGAHW_DECLARE(AGNUS_PAL); /* Normal/Fat PAL Agnus (8367/8371) */ + AMIGAHW_DECLARE(AGNUS_NTSC); /* Normal/Fat NTSC Agnus (8361/8370) */ + AMIGAHW_DECLARE(AGNUS_HR_PAL); /* Fat Hires PAL Agnus (8372) */ + AMIGAHW_DECLARE(AGNUS_HR_NTSC); /* Fat Hires NTSC Agnus (8372) */ + AMIGAHW_DECLARE(ALICE_PAL); /* PAL Alice (8374) */ + AMIGAHW_DECLARE(ALICE_NTSC); /* NTSC Alice (8374) */ + AMIGAHW_DECLARE(MAGIC_REKICK); /* A3000 Magic Hard Rekick */ + AMIGAHW_DECLARE(ZORRO); /* Zorro AutoConfig */ + } hw_present; +}; + +#else /* __ASSEMBLY__ */ + +BI_amiga_model = BI_un +BI_amiga_num_autcon = BI_amiga_model+4 +BI_amiga_autocon = BI_amiga_num_autcon+4 +#ifdef HACKER_KERNEL +BI_amiga_exit_func = BI_amiga_autocon+(CD_sizeof*NUM_AUTO) +BI_amiga_chip_addr = BI_amiga_exit_func+4 +BI_amiga_chip_size = BI_amiga_chip_addr+4 +#else +BI_amiga_chip_size = BI_amiga_autocon+(CD_sizeof*NUM_AUTO) +#endif +BI_amiga_vblank = BI_amiga_chip_size+4 +BI_amiga_psfreq = BI_amiga_vblank+1 +BI_amiga_eclock = BI_amiga_psfreq+1 +BI_amiga_chipset = BI_amiga_eclock+4 +BI_amiga_hw_present = BI_amiga_chipset+4 + +#endif /* __ASSEMBLY__ */ + +/* Atari specific part of bootinfo */ + +/* + * Define several Hardware-Chips for indication so that for the ATARI we do + * no longer decide whether it is a Falcon or other machine . It's just + * important what hardware the machine uses + */ + +/* ++roman 08/08/95: rewritten from ORing constants to a C bitfield */ + +#ifndef __ASSEMBLY__ + +#define ATARIHW_DECLARE(name) unsigned name : 1 +#define ATARIHW_SET(name) (boot_info.bi_atari.hw_present.name = 1) +#define ATARIHW_PRESENT(name) (boot_info.bi_atari.hw_present.name) + +struct bi_Atari { + struct { + /* video hardware */ + ATARIHW_DECLARE(STND_SHIFTER); /* ST-Shifter - no base low ! */ + ATARIHW_DECLARE(EXTD_SHIFTER); /* STe-Shifter - 24 bit address */ + ATARIHW_DECLARE(TT_SHIFTER); /* TT-Shifter */ + ATARIHW_DECLARE(VIDEL_SHIFTER); /* Falcon-Shifter */ + /* sound hardware */ + ATARIHW_DECLARE(YM_2149); /* Yamaha YM 2149 */ + ATARIHW_DECLARE(PCM_8BIT); /* PCM-Sound in STe-ATARI */ + ATARIHW_DECLARE(CODEC); /* CODEC Sound (Falcon) */ + /* disk storage interfaces */ + ATARIHW_DECLARE(TT_SCSI); /* Directly mapped NCR5380 */ + ATARIHW_DECLARE(ST_SCSI); /* NCR5380 via ST-DMA (Falcon) */ + ATARIHW_DECLARE(ACSI); /* Standard ACSI like in STs */ + ATARIHW_DECLARE(IDE); /* IDE Interface */ + ATARIHW_DECLARE(FDCSPEED); /* 8/16 MHz switch for FDC */ + /* other I/O hardware */ + ATARIHW_DECLARE(ST_MFP); /* The ST-MFP (there should + be no Atari without + it... but who knows?) */ + ATARIHW_DECLARE(TT_MFP); /* 2nd MFP */ + ATARIHW_DECLARE(SCC); /* Serial Communications Contr. */ + ATARIHW_DECLARE(ST_ESCC); /* SCC Z83230 in an ST */ + ATARIHW_DECLARE(ANALOG_JOY); /* Paddle Interface for STe + and Falcon */ + ATARIHW_DECLARE(MICROWIRE); /* Microwire Interface */ + /* DMA */ + ATARIHW_DECLARE(STND_DMA); /* 24 Bit limited ST-DMA */ + ATARIHW_DECLARE(EXTD_DMA); /* 32 Bit ST-DMA */ + ATARIHW_DECLARE(SCSI_DMA); /* DMA for the NCR5380 */ + ATARIHW_DECLARE(SCC_DMA); /* DMA for the SCC */ + /* real time clocks */ + ATARIHW_DECLARE(TT_CLK); /* TT compatible clock chip */ + ATARIHW_DECLARE(MSTE_CLK); /* Mega ST(E) clock chip */ + /* supporting hardware */ + ATARIHW_DECLARE(SCU); /* System Control Unit */ + ATARIHW_DECLARE(BLITTER); /* Blitter */ + ATARIHW_DECLARE(VME); /* VME Bus */ + } hw_present; + unsigned long mch_cookie; /* _MCH cookie from TOS */ +}; + +/* mch_cookie values (upper word) */ +#define ATARI_MCH_ST 0 +#define ATARI_MCH_STE 1 +#define ATARI_MCH_TT 2 +#define ATARI_MCH_FALCON 3 + +struct mem_info { + unsigned long addr; /* physical address of memory chunk */ + unsigned long size; /* length of memory chunk (in bytes) */ +}; + +#else /* __ASSEMBLY__ */ + +MI_addr = 0 +MI_size = MI_addr+4 +MI_sizeof = MI_size+4 + +#endif /* __ASSEMBLY__ */ + +#define NUM_MEMINFO 4 + +#define MACH_AMIGA 1 +#define MACH_ATARI 2 +#define MACH_MAC 3 + +/* + * CPU and FPU types + */ + +#define CPUB_68020 0 +#define CPUB_68030 1 +#define CPUB_68040 2 +#define CPUB_68060 3 +#define FPUB_68881 5 +#define FPUB_68882 6 +#define FPUB_68040 7 /* Internal FPU */ +#define FPUB_68060 8 /* Internal FPU */ + +#define CPU_68020 (1<<CPUB_68020) +#define CPU_68030 (1<<CPUB_68030) +#define CPU_68040 (1<<CPUB_68040) +#define CPU_68060 (1<<CPUB_68060) +#define CPU_MASK (31) +#define FPU_68881 (1<<FPUB_68881) +#define FPU_68882 (1<<FPUB_68882) +#define FPU_68040 (1<<FPUB_68040) /* Internal FPU */ +#define FPU_68060 (1<<FPUB_68060) /* Internal FPU */ +#define FPU_MASK (0xfe0) + +#define CL_SIZE (256) + +/* + * machine type definitions + */ + +#if !defined(CONFIG_AMIGA) +# define MACH_IS_AMIGA (0) +#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) +# define MACH_IS_AMIGA (boot_info.machtype == MACH_AMIGA) +#else +# define CONFIG_AMIGA_ONLY +# define MACH_IS_AMIGA (1) +# define MACH_TYPE (MACH_AMIGA) +#endif + +#if !defined(CONFIG_ATARI) +# define MACH_IS_ATARI (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) +# define MACH_IS_ATARI (boot_info.machtype == MACH_ATARI) +#else +# define CONFIG_ATARI_ONLY +# define MACH_IS_ATARI (1) +# define MACH_TYPE (MACH_ATARI) +#endif + +#if defined(CONFIG_MAC) +# error Currently no Mac support! +#endif + +#ifndef MACH_TYPE +# define MACH_TYPE (boot_info.machtype) +#endif + +/* + * cpu type definitions + */ + +#if !defined(CONFIG_M68020) +# define CPU_IS_020 (0) +#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_020 (boot_info.cputype & CPU_68020) +#else +# define CONFIG_M68020_ONLY +# define CPU_IS_020 (1) +#endif + +#if !defined(CONFIG_M68030) +# define CPU_IS_030 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_030 (boot_info.cputype & CPU_68030) +#else +# define CONFIG_M68030_ONLY +# define CPU_IS_030 (1) +#endif + +#if !defined(CONFIG_M68040) +# define CPU_IS_040 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060) +# define CPU_IS_040 (boot_info.cputype & CPU_68040) +#else +# define CONFIG_M68040_ONLY +# define CPU_IS_040 (1) +#endif + +#if !defined(CONFIG_M68060) +# define CPU_IS_060 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040) +# define CPU_IS_060 (boot_info.cputype & CPU_68060) +#else +# define CONFIG_M68060_ONLY +# define CPU_IS_060 (1) +#endif + +#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030) +# define CPU_IS_020_OR_030 (0) +#else +# define CONFIG_M68020_OR_M68030 +# if defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_020_OR_030 (!m68k_is040or060) +# else +# define CONFIG_M68020_OR_M68030_ONLY +# define CPU_IS_020_OR_030 (1) +# endif +#endif + +#if !defined(CONFIG_M68040) && !defined(CONFIG_M68060) +# define CPU_IS_040_OR_060 (0) +#else +# define CONFIG_M68040_OR_M68060 +# if defined(CONFIG_M68020) || defined(CONFIG_M68030) +# define CPU_IS_040_OR_060 (m68k_is040or060) +# else +# define CONFIG_M68040_OR_M68060_ONLY +# define CPU_IS_040_OR_060 (1) +# endif +#endif + +#define CPU_TYPE (boot_info.cputype) + +#ifndef __ASSEMBLY__ +#ifdef __KERNEL__ + /* + * m68k_is040or060 is != 0 for a '040 or higher; + * used numbers are 4 for 68040 and 6 for 68060. + */ + +extern int m68k_is040or060; +#endif + +struct bootinfo { + unsigned long machtype; /* machine type */ + unsigned long cputype; /* system CPU & FPU */ + struct mem_info memory[NUM_MEMINFO]; /* memory description */ + int num_memory; /* # of memory blocks found */ + unsigned long ramdisk_size; /* ramdisk size in 1024 byte blocks */ + unsigned long ramdisk_addr; /* address of the ram disk in mem */ + char command_line[CL_SIZE]; /* kernel command line parameters */ + union { + struct bi_Amiga bi_ami; /* Amiga specific information */ + struct bi_Atari bi_ata; /* Atari specific information */ + } bi_un; +}; +#define bi_amiga bi_un.bi_ami +#define bi_atari bi_un.bi_ata +#define bi_mac bi_un.bi_mac + +extern struct bootinfo + boot_info; + +#else /* __ASSEMBLY__ */ + +BI_machtype = 0 +BI_cputype = BI_machtype+4 +BI_memory = BI_cputype+4 +BI_num_memory = BI_memory+(MI_sizeof*NUM_MEMINFO) +BI_ramdisk_size = BI_num_memory+4 +BI_ramdisk_addr = BI_ramdisk_size+4 +BI_command_line = BI_ramdisk_addr+4 +BI_un = BI_command_line+CL_SIZE + +#endif /* __ASSEMBLY__ */ + + +/* + * Stuff for bootinfo interface versioning + * + * At the start of kernel code, a 'struct bootversion' is located. bootstrap + * checks for a matching version of the interface before booting a kernel, to + * avoid user confusion if kernel and bootstrap don't work together :-) + * + * If incompatible changes are made to the bootinfo interface, the major + * number below should be stepped (and the minor reset to 0) for the + * appropriate machine. If a change is backward-compatible, the minor should + * be stepped. "Backwards-compatible" means that booting will work, but + * certain features may not. + */ + +#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */ +#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor)) +#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff) +#define BI_VERSION_MINOR(v) ((v) & 0xffff) + +#ifndef __ASSEMBLY__ + +struct bootversion { + unsigned short branch; + unsigned long magic; + struct { + unsigned long machtype; + unsigned long version; + } machversions[0]; +}; + +#endif /* __ASSEMBLY__ */ + +#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) +#define ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) + +#endif /* _M68K_SETUP_H */ diff --git a/include/asm-m68k/shm.h b/include/asm-m68k/shm.h new file mode 100644 index 000000000..f59bbc39f --- /dev/null +++ b/include/asm-m68k/shm.h @@ -0,0 +1,24 @@ +#ifndef _M68K_SHM_H +#define _M68K_SHM_H + +/* format of page table entries that correspond to shared memory pages + currently out in swap space (see also mm/swap.c): + bits 0-1 (PAGE_PRESENT) is = 0 + bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE + bits 31..9 are used like this: + bits 15..9 (SHM_ID) the id of the shared memory segment + bits 30..16 (SHM_IDX) the index of the page within the shared memory segment + (actually only bits 25..16 get used since SHMMAX is so low) + bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach +*/ +/* on the m68k both bits 0 and 1 must be zero */ + +#define SHM_ID_SHIFT 9 +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +#endif /* _M68K_SHM_H */ diff --git a/include/asm-m68k/shmparam.h b/include/asm-m68k/shmparam.h new file mode 100644 index 000000000..d9e6a9e05 --- /dev/null +++ b/include/asm-m68k/shmparam.h @@ -0,0 +1,44 @@ +#ifndef _M68K_SHMPARAM_H +#define _M68K_SHMPARAM_H + +/* address range for shared memory attaches if no address passed to shmat() */ +#define SHM_RANGE_START 0xC0000000 +#define SHM_RANGE_END 0xD0000000 + +/* + * Format of a swap-entry for shared memory pages currently out in + * swap space (see also mm/swap.c). + * + * SWP_TYPE = SHM_SWP_TYPE + * SWP_OFFSET is used as follows: + * + * bits 0..6 : id of shared memory segment page belongs to (SHM_ID) + * bits 7..21: index of page within shared memory segment (SHM_IDX) + * (actually fewer bits get used since SHMMAX is so low) + */ + +/* + * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and + * there is a static array of size SHMMNI. + */ +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +/* + * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and + * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS). + */ + +#define SHMMAX 0x1000000 /* max shared seg size (bytes) */ +#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */ +#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */ +#define SHMALL /* max shm system wide (pages) */ \ + (1<<(_SHM_IDX_BITS+_SHM_ID_BITS)) +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ +#define SHMSEG SHMMNI /* max shared segs per process */ + +#endif /* _M68K_SHMPARAM_H */ diff --git a/include/asm-m68k/sigcontext.h b/include/asm-m68k/sigcontext.h new file mode 100644 index 000000000..a2d28c218 --- /dev/null +++ b/include/asm-m68k/sigcontext.h @@ -0,0 +1,19 @@ +#ifndef _ASM_M68k_SIGCONTEXT_H +#define _ASM_M68k_SIGCONTEXT_H + +struct sigcontext { + unsigned long sc_mask; /* old sigmask */ + unsigned long sc_usp; /* old user stack pointer */ + unsigned long sc_d0; + unsigned long sc_d1; + unsigned long sc_a0; + unsigned long sc_a1; + unsigned short sc_sr; + unsigned long sc_pc; + unsigned short sc_formatvec; + unsigned long sc_fpregs[2*3]; /* room for two fp registers */ + unsigned long sc_fpcntl[3]; + unsigned char sc_fpstate[216]; +}; + +#endif diff --git a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h new file mode 100644 index 000000000..1069ccc55 --- /dev/null +++ b/include/asm-m68k/signal.h @@ -0,0 +1,96 @@ +#ifndef _M68K_SIGNAL_H +#define _M68K_SIGNAL_H + +typedef unsigned long sigset_t; /* at least 32 bits */ + +#define _NSIG 32 +#define NSIG _NSIG + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGUNUSED 31 + +/* + * sa_flags values: SA_STACK is not currently supported, but will allow the + * usage of signal stacks by using the (now obsolete) sa_restorer field in + * the sigaction structure as a stack pointer. This is now possible due to + * the changes in signal handling. LBT 010493. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. + */ +#define SA_NOCLDSTOP 1 +#define SA_SHIRQ 0x04000000 +#define SA_STACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_INTERRUPT 0x20000000 +#define SA_NOMASK 0x40000000 +#define SA_ONESHOT 0x80000000 + +#ifdef __KERNEL__ +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#endif + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(int); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct sigaction { + __sighandler_t sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#ifdef __KERNEL__ +#include <asm/sigcontext.h> +#endif + +#endif /* _M68K_SIGNAL_H */ diff --git a/include/asm-m68k/socket.h b/include/asm-m68k/socket.h new file mode 100644 index 000000000..529a3ffef --- /dev/null +++ b/include/asm-m68k/socket.h @@ -0,0 +1,25 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockoptions(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-m68k/sockios.h b/include/asm-m68k/sockios.h new file mode 100644 index 000000000..85ace3da5 --- /dev/null +++ b/include/asm-m68k/sockios.h @@ -0,0 +1,12 @@ +#ifndef __ARCH_M68K_SOCKIOS__ +#define __ARCH_M68K_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ + +#endif /* __ARCH_M68K_SOCKIOS__ */ diff --git a/include/asm-m68k/stat.h b/include/asm-m68k/stat.h new file mode 100644 index 000000000..919520ff1 --- /dev/null +++ b/include/asm-m68k/stat.h @@ -0,0 +1,41 @@ +#ifndef _M68K_STAT_H +#define _M68K_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _M68K_STAT_H */ diff --git a/include/asm-m68k/statfs.h b/include/asm-m68k/statfs.h new file mode 100644 index 000000000..1ee08965d --- /dev/null +++ b/include/asm-m68k/statfs.h @@ -0,0 +1,25 @@ +#ifndef _M68K_STATFS_H +#define _M68K_STATFS_H + +#ifndef __KERNEL_STRICT_NAMES + +#include <linux/types.h> + +typedef __kernel_fsid_t fsid_t; + +#endif + +struct statfs { + long f_type; + long f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + +#endif /* _M68K_STATFS_H */ diff --git a/include/asm-m68k/string.h b/include/asm-m68k/string.h index 70466ed5e..57f83e3fc 100644 --- a/include/asm-m68k/string.h +++ b/include/asm-m68k/string.h @@ -1,20 +1,23 @@ #ifndef _M68K_STRING_H_ #define _M68K_STRING_H_ -#define __USE_PORTABLE_STRINGS_H_ +#include <linux/config.h> +#include <asm/page.h> +#define __HAVE_ARCH_STRCPY extern inline char * strcpy(char * dest,const char *src) { char *xdest = dest; __asm__ __volatile__ ("1:\tmoveb %1@+,%0@+\n\t" - "bne 1b" + "jne 1b" : "=a" (dest), "=a" (src) : "0" (dest), "1" (src) : "memory"); return xdest; } +#define __HAVE_ARCH_STRNCPY extern inline char * strncpy(char *dest, const char *src, size_t n) { char *xdest = dest; @@ -24,9 +27,9 @@ extern inline char * strncpy(char *dest, const char *src, size_t n) __asm__ __volatile__ ("1:\tmoveb %1@+,%0@+\n\t" - "beq 2f\n\t" + "jeq 2f\n\t" "subql #1,%2\n\t" - "bne 1b\n\t" + "jne 1b\n\t" "2:" : "=a" (dest), "=a" (src), "=d" (n) : "0" (dest), "1" (src), "2" (n) @@ -34,10 +37,116 @@ extern inline char * strncpy(char *dest, const char *src, size_t n) return xdest; } -#define __USE_PORTABLE_strcat +#define __HAVE_ARCH_STRCAT +extern inline char * strcat(char * dest, const char * src) +{ + char *tmp = dest; + + while (*dest) + dest++; + while ((*dest++ = *src++)) + ; + + return tmp; +} -#define __USE_PORTABLE_strncat +#define __HAVE_ARCH_STRNCAT +extern inline char * strncat(char *dest, const char *src, size_t count) +{ + char *tmp = dest; + + if (count) { + while (*dest) + dest++; + while ((*dest++ = *src++)) { + if (--count == 0) { + *dest++='\0'; + break; + } + } + } + + return tmp; +} +#define __HAVE_ARCH_STRCHR +extern inline char * strchr(const char * s, int c) +{ + const char ch = c; + + for(; *s != ch; ++s) + if (*s == '\0') + return( NULL ); + return( (char *) s); +} + +#define __HAVE_ARCH_STRPBRK +extern inline char * strpbrk(const char * cs,const char * ct) +{ + const char *sc1,*sc2; + + for( sc1 = cs; *sc1 != '\0'; ++sc1) + for( sc2 = ct; *sc2 != '\0'; ++sc2) + if (*sc1 == *sc2) + return((char *) sc1); + return( NULL ); +} + +#define __HAVE_ARCH_STRSPN +extern inline size_t strspn(const char *s, const char *accept) +{ + const char *p; + const char *a; + size_t count = 0; + + for (p = s; *p != '\0'; ++p) + { + for (a = accept; *a != '\0'; ++a) + if (*p == *a) + break; + if (*a == '\0') + return count; + else + ++count; + } + + return count; +} + +#define __HAVE_ARCH_STRTOK +extern inline char * strtok(char * s,const char * ct) +{ + char *sbegin, *send; + + sbegin = s ? s : ___strtok; + if (!sbegin) { + return NULL; + } + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') { + ___strtok = NULL; + return( NULL ); + } + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + ___strtok = send; + return (sbegin); +} + +/* strstr !! */ + +#define __HAVE_ARCH_STRLEN +extern inline size_t strlen(const char * s) +{ + const char *sc; + for (sc = s; *sc != '\0'; ++sc) ; + return(sc - s); +} + +/* strnlen !! */ + +#define __HAVE_ARCH_STRCMP extern inline int strcmp(const char * cs,const char * ct) { char __res; @@ -45,10 +154,10 @@ extern inline int strcmp(const char * cs,const char * ct) __asm__ ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ "cmpb %1@+,%2\n\t" /* compare a byte */ - "bne 2f\n\t" /* not equal, break out */ + "jne 2f\n\t" /* not equal, break out */ "tstb %2\n\t" /* at end of cs? */ - "bne 1b\n\t" /* no, keep going */ - "bra 3f\n\t" /* strings are equal */ + "jne 1b\n\t" /* no, keep going */ + "jra 3f\n\t" /* strings are equal */ "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */ "3:" : "=a" (cs), "=a" (ct), "=d" (__res) @@ -56,6 +165,7 @@ extern inline int strcmp(const char * cs,const char * ct) return __res; } +#define __HAVE_ARCH_STRNCMP extern inline int strncmp(const char * cs,const char * ct,size_t count) { char __res; @@ -65,13 +175,13 @@ extern inline int strncmp(const char * cs,const char * ct,size_t count) __asm__ ("1:\tmovb %0@+,%3\n\t" /* get *cs */ "cmpb %1@+,%3\n\t" /* compare a byte */ - "bne 3f\n\t" /* not equal, break out */ + "jne 3f\n\t" /* not equal, break out */ "tstb %3\n\t" /* at end of cs? */ - "beq 4f\n\t" /* yes, all done */ + "jeq 4f\n\t" /* yes, all done */ "subql #1,%2\n\t" /* no, adjust count */ - "bne 1b\n\t" /* more to do, keep going */ + "jne 1b\n\t" /* more to do, keep going */ "2:\tmoveq #0,%3\n\t" /* strings are equal */ - "bra 4f\n\t" + "jra 4f\n\t" "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */ "4:" : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res) @@ -79,76 +189,353 @@ extern inline int strncmp(const char * cs,const char * ct,size_t count) return __res; } -#define __USE_PORTABLE_strchr +#define __HAVE_ARCH_MEMSET +/* + * This is really ugly, but its highly optimizatiable by the + * compiler and is meant as compensation for gcc's missing + * __builtin_memset(). For the 680[23]0 it might be worth considering + * the optimal number of misaligned writes compared to the number of + * tests'n'branches needed to align the destination address. The + * 680[46]0 doesn't really care due to their copy-back caches. + * 10/09/96 - Jes Sorensen + */ +extern inline void * __memset_g(void * s, int c, size_t count) +{ + void *xs = s; + size_t temp; + + if (!count) + return xs; -#define __USE_PORTABLE_strlen + c &= 0xff; + c |= c << 8; + c |= c << 16; -#define __USE_PORTABLE_strspn + if (count < 36){ + long *ls = s; -#define __USE_PORTABLE_strpbrk + switch(count){ + case 32: case 33: case 34: case 35: + *ls++ = c; + case 28: case 29: case 30: case 31: + *ls++ = c; + case 24: case 25: case 26: case 27: + *ls++ = c; + case 20: case 21: case 22: case 23: + *ls++ = c; + case 16: case 17: case 18: case 19: + *ls++ = c; + case 12: case 13: case 14: case 15: + *ls++ = c; + case 8: case 9: case 10: case 11: + *ls++ = c; + case 4: case 5: case 6: case 7: + *ls++ = c; + break; + default: + break; + } + s = ls; + if (count & 0x02){ + short *ss = s; + *ss++ = c; + s = ss; + } + if (count & 0x01){ + char *cs = s; + *cs++ = c; + s = cs; + } + return xs; + } -#define __USE_PORTABLE_strtok + if ((long) s & 1) + { + char *cs = s; + *cs++ = c; + s = cs; + count--; + } + if (count > 2 && (long) s & 2) + { + short *ss = s; + *ss++ = c; + s = ss; + count -= 2; + } + temp = count >> 2; + if (temp) + { + long *ls = s; + temp--; + do + *ls++ = c; + while (temp--); + s = ls; + } + if (count & 2) + { + short *ss = s; + *ss++ = c; + s = ss; + } + if (count & 1) + { + char *cs = s; + *cs = c; + } + return xs; +} -extern inline void * memset(void * s,char c,size_t count) +/* + * __memset_page assumes that data is longword aligned. Most, if not + * all, of these page sized memsets are performed on page aligned + * areas, thus we do not need to check if the destination is longword + * aligned. Of course we suffer a serious performance loss if this is + * not the case but I think the risk of this ever happening is + * extremely small. We spend a lot of time clearing pages in + * get_empty_page() so I think it is worth it anyway. Besides, the + * 680[46]0 do not really care about misaligned writes due to their + * copy-back cache. + * + * The optimized case for the 680[46]0 is implemented using the move16 + * instruction. My tests showed that this implementation is 35-45% + * faster than the original implementation using movel, the only + * caveat is that the destination address must be 16-byte aligned. + * 01/09/96 - Jes Sorensen + */ +extern inline void * __memset_page(void * s,int c,size_t count) { - void *xs = s; + unsigned long data, tmp; + void *xs, *sp; + + xs = sp = s; + + c = c & 255; + data = c | (c << 8); + data |= data << 16; + +#if defined(CONFIG_OPTIMIZE_040) || defined(CONFIG_OPTIMIZE_060) + + if (((unsigned long) s) & 0x0f) + memset(s, c, count); + else{ + *((unsigned long *)(s))++ = data; + *((unsigned long *)(s))++ = data; + *((unsigned long *)(s))++ = data; + *((unsigned long *)(s))++ = data; + + __asm__ __volatile__("1:\t" + "move16 %2@+,%0@+\n\t" + "subqw #8,%2\n\t" + "subqw #8,%2\n\t" + "dbra %1,1b\n\t" + : "=a" (s), "=d" (tmp) + : "a" (sp), "0" (s), "1" ((count - 16) / 16 - 1) + ); + } + +#else + __asm__ __volatile__("1:\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "movel %2,%0@+\n\t" + "dbra %1,1b\n\t" + : "=a" (s), "=d" (tmp) + : "d" (data), "0" (s), "1" (count / 32 - 1) + ); +#endif - if (!count) - return xs; - __asm__ __volatile__ - ("1:\tmoveb %3,%0@+\n\t" - "subql #1,%1\n\t" - "bne 1b" - : "=a" (s), "=d" (count) - : "0" (s), "d" (c), "1" (count) - : "memory"); return xs; } -extern inline void * memcpy(void * to, const void * from, size_t n) +#define __memset_const(s,c,count) \ +((count==PAGE_SIZE) ? \ + __memset_page((s),(c),(count)) : \ + __memset_g((s),(c),(count))) + +#define memset(s, c, count) \ +(__builtin_constant_p(count) ? \ + __memset_const((s),(c),(count)) : \ + memset((s),(c),(count))) + +#define __HAVE_ARCH_MEMCPY +/* + * __builtin_memcpy() does not handle page-sized memcpys very well, + * thus following the same assumptions as for page-sized memsets, this + * function copies page-sized areas using an unrolled loop, without + * considering alignment. + * + * For the 680[46]0 only kernels we use the move16 instruction instead + * as it writes through the data-cache, invalidating the cache-lines + * touched. In this way we do not use up the entire data-cache (well, + * half of it on the 68060) by copying a page. An unrolled loop of two + * move16 instructions seem to the fastest. The only caveat is that + * both source and destination must be 16-byte aligned, if not we fall + * back to the generic memcpy function. - Jes + */ +extern inline void * __memcpy_page(void * to, const void * from, size_t count) { + unsigned long tmp; void *xto = to; - if (!n) - return xto; - __asm__ __volatile__ - ("1:\tmoveb %1@+,%0@+\n\t" - "subql #1,%2\n\t" - "bne 1b" - : "=a" (to), "=a" (from), "=d" (n) - : "0" (to), "1" (from), "2" (n) - : "memory" ); +#if defined(CONFIG_OPTIMIZE_040) || defined(CONFIG_OPTIMIZE_060) + + if (((unsigned long) to | (unsigned long) from) & 0x0f) + return memcpy(to, from, count); + + __asm__ __volatile__("1:\t" + "move16 %1@+,%0@+\n\t" + "move16 %1@+,%0@+\n\t" + "dbra %2,1b\n\t" + : "=a" (to), "=a" (from), "=d" (tmp) + : "0" (to), "1" (from) , "2" (count / 32 - 1) + ); +#else + __asm__ __volatile__("1:\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "movel %1@+,%0@+\n\t" + "dbra %2,1b\n\t" + : "=a" (to), "=a" (from), "=d" (tmp) + : "0" (to), "1" (from) , "2" (count / 32 - 1) + ); +#endif return xto; } +#define __memcpy_const(to, from, n) \ +((n==PAGE_SIZE) ? \ + __memcpy_page((to),(from),(n)) : \ + __builtin_memcpy((to),(from),(n))) + +#define memcpy(to, from, n) \ +(__builtin_constant_p(n) ? \ + __memcpy_const((to),(from),(n)) : \ + memcpy((to),(from),(n))) + +#define __HAVE_ARCH_MEMMOVE extern inline void * memmove(void * dest,const void * src, size_t n) { void *xdest = dest; + size_t temp; if (!n) return xdest; if (dest < src) - __asm__ __volatile__ - ("1:\tmoveb %1@+,%0@+\n\t" - "subql #1,%2\n\t" - "bne 1b" - : "=a" (dest), "=a" (src), "=d" (n) - : "0" (dest), "1" (src), "2" (n) - : "memory" ); + { + if ((long) dest & 1) + { + char *cdest = dest; + const char *csrc = src; + *cdest++ = *csrc++; + dest = cdest; + src = csrc; + n--; + } + if (n > 2 && (long) dest & 2) + { + short *sdest = dest; + const short *ssrc = src; + *sdest++ = *ssrc++; + dest = sdest; + src = ssrc; + n -= 2; + } + temp = n >> 2; + if (temp) + { + long *ldest = dest; + const long *lsrc = src; + temp--; + do + *ldest++ = *lsrc++; + while (temp--); + dest = ldest; + src = lsrc; + } + if (n & 2) + { + short *sdest = dest; + const short *ssrc = src; + *sdest++ = *ssrc++; + dest = sdest; + src = ssrc; + } + if (n & 1) + { + char *cdest = dest; + const char *csrc = src; + *cdest = *csrc; + } + } else - __asm__ __volatile__ - ("1:\tmoveb %1@-,%0@-\n\t" - "subql #1,%2\n\t" - "bne 1b" - : "=a" (dest), "=a" (src), "=d" (n) - : "0" (dest+n), "1" (src+n), "2" (n) - : "memory" ); + { + dest = (char *) dest + n; + src = (const char *) src + n; + if ((long) dest & 1) + { + char *cdest = dest; + const char *csrc = src; + *--cdest = *--csrc; + dest = cdest; + src = csrc; + n--; + } + if (n > 2 && (long) dest & 2) + { + short *sdest = dest; + const short *ssrc = src; + *--sdest = *--ssrc; + dest = sdest; + src = ssrc; + n -= 2; + } + temp = n >> 2; + if (temp) + { + long *ldest = dest; + const long *lsrc = src; + temp--; + do + *--ldest = *--lsrc; + while (temp--); + dest = ldest; + src = lsrc; + } + if (n & 2) + { + short *sdest = dest; + const short *ssrc = src; + *--sdest = *--ssrc; + dest = sdest; + src = ssrc; + } + if (n & 1) + { + char *cdest = dest; + const char *csrc = src; + *--cdest = *--csrc; + } + } return xdest; } -#define __USE_PORTABLE_memcmp - -#define __USE_PORTABLE_memscan +#define __HAVE_ARCH_MEMCMP +#define memcmp(cs, ct, n) \ +(__builtin_constant_p(n) ? \ + __builtin_memcmp((cs),(ct),(n)) : \ + memcmp((cs),(ct),(n))) #endif /* _M68K_STRING_H_ */ diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h index e987f1f46..859c748e3 100644 --- a/include/asm-m68k/system.h +++ b/include/asm-m68k/system.h @@ -1,53 +1,153 @@ +#ifndef _M68K_SYSTEM_H +#define _M68K_SYSTEM_H + +#include <linux/config.h> /* get configuration macros */ +#include <linux/linkage.h> +#include <asm/segment.h> + +extern inline unsigned long rdusp(void) { + unsigned long usp; + + __asm__ __volatile__("movec %/usp,%0" + : "=d" (usp)); + return usp; +} + +extern inline void wrusp(unsigned long usp) { + __asm__ __volatile__("movec %0,%/usp" + : + : "d" (usp)); +} + /* - * linux/include/asm-m68k/system.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive - * for more details. + * switch_to(n) should switch tasks to task ptr, first checking that + * ptr isn't the current task, in which case it does nothing. This + * also clears the TS-flag if the task we switched to has used the + * math co-processor latest. */ - /* - * 680x0 support added by Hamish Macdonald + * switch_to() saves the extra registers, that are not saved + * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and + * a0-a1. Some of these are used by schedule() and its predecessors + * and so we might get see unexpected behaviors when a task returns + * with unexpected register values. + * + * syscall stores these registers itself and none of them are used + * by syscall after the function in the syscall has been called. + * + * Beware that resume now expects *next to be in d1 and the offset of + * tss to be in a1. This saves a few instructions as we no longer have + * to push them onto the stack and read them back right after. + * + * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) + * + * Changed 96/09/19 by Andreas Schwab + * pass prev in a0, next in a1, offset of tss in d1, and whether + * the mm structures are shared in d2 (to avoid atc flushing). */ +asmlinkage void resume(void); +#define switch_to(prev,next) { \ + register void *_prev __asm__ ("a0") = (prev); \ + register void *_next __asm__ ("a1") = (next); \ + register int _tssoff __asm__ ("d1") = (int)&((struct task_struct *)0)->tss; \ + register char _shared __asm__ ("d2") = ((prev)->mm == (next)->mm); \ + __asm__ __volatile__("jbsr " SYMBOL_NAME_STR(resume) "\n\t" \ + : : "a" (_prev), "a" (_next), "d" (_tssoff), \ + "d" (_shared) \ + : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1"); \ +} -#ifndef _M68K_SYSTEM_H -#define _M68K_SYSTEM_H +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) -#include <linux/config.h> /* get configuration macros */ +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC) /* block out HSYNC on the atari */ -#define sti() __asm__ __volatile__ ("andiw #0xfbff,sr": : : "memory") +#define sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory") #else /* portable version */ -#define sti() __asm__ __volatile__ ("andiw #0xf8ff,sr": : : "memory") +#define sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") #endif /* machine compilation types */ -#define cli() __asm__ __volatile__ ("oriw #0x0700,sr": : : "memory") +#define cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") #define nop() __asm__ __volatile__ ("nop"::) +#define mb() __asm__ __volatile__ ("" : : :"memory") #define save_flags(x) \ -__asm__ __volatile__("movew sr,%0":"=d" (x) : /* no input */ :"memory") +__asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory") #define restore_flags(x) \ -__asm__ __volatile__("movew %0,sr": /* no outputs */ :"d" (x) : "memory") +__asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory") #define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc") -#define move_to_user_mode() \ - __asm__ __volatile__ ("movel sp,usp\n\t" /* setup user sp */ \ - "movec %0,msp\n\t" /* setup kernel sp */ \ - "andiw #0xdfff,sr" /* return to user mode */ \ - : /* no output */ \ - : "r" (current->kernel_stack_page + PAGE_SIZE) \ - : "memory", "sp") - -static inline void clear_fpu(void) { - unsigned long nilstate = 0; - __asm__ __volatile__ ("frestore %0@" : : "a" (&nilstate)); +#ifndef CONFIG_RMW_INSNS +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + unsigned long tmp, flags; + + save_flags(flags); + cli(); + + switch (size) { + case 1: + __asm__ __volatile__ + ("moveb %2,%0\n\t" + "moveb %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("movew %2,%0\n\t" + "movew %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("movel %2,%0\n\t" + "movel %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + } + restore_flags(flags); + return tmp; } +#else +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + switch (size) { + case 1: + __asm__ __volatile__ + ("moveb %2,%0\n\t" + "1:\n\t" + "casb %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("movew %2,%0\n\t" + "1:\n\t" + "casw %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("movel %2,%0\n\t" + "1:\n\t" + "casl %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + } + return x; +} +#endif -#define halt() \ - __asm__ __volatile__ ("halt") +/* + * Reset the machine. + */ +extern void hard_reset_now(void); #endif /* _M68K_SYSTEM_H */ diff --git a/include/asm-m68k/termbits.h b/include/asm-m68k/termbits.h new file mode 100644 index 000000000..78494acc0 --- /dev/null +++ b/include/asm-m68k/termbits.h @@ -0,0 +1,162 @@ +#ifndef __ARCH_M68K_TERMBITS_H__ +#define __ARCH_M68K_TERMBITS_H__ + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* __ARCH_M68K_TERMBITS_H__ */ diff --git a/include/asm-m68k/termios.h b/include/asm-m68k/termios.h new file mode 100644 index 000000000..4bedde47f --- /dev/null +++ b/include/asm-m68k/termios.h @@ -0,0 +1,90 @@ +#ifndef _M68K_TERMIOS_H +#define _M68K_TERMIOS_H + +#include <asm/termbits.h> +#include <asm/ioctls.h> + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +extern inline void trans_from_termio(struct termio * termio, + struct termios * termios) +{ +#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) + SET_LOW_BITS(termios->c_iflag, termio->c_iflag); + SET_LOW_BITS(termios->c_oflag, termio->c_oflag); + SET_LOW_BITS(termios->c_cflag, termio->c_cflag); + SET_LOW_BITS(termios->c_lflag, termio->c_lflag); +#undef SET_LOW_BITS + memcpy(termios->c_cc, termio->c_cc, NCC); +} + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +extern inline void trans_to_termio(struct termios * termios, + struct termio * termio) +{ + termio->c_iflag = termios->c_iflag; + termio->c_oflag = termios->c_oflag; + termio->c_cflag = termios->c_cflag; + termio->c_lflag = termios->c_lflag; + termio->c_line = termios->c_line; + memcpy(termio->c_cc, termios->c_cc, NCC); +} + +#endif /* __KERNEL__ */ + +#endif /* _M68K_TERMIOS_H */ diff --git a/include/asm-m68k/traps.h b/include/asm-m68k/traps.h new file mode 100644 index 000000000..5b12398f5 --- /dev/null +++ b/include/asm-m68k/traps.h @@ -0,0 +1,241 @@ +/* + * linux/include/asm/traps.h + * + * Copyright (C) 1993 Hamish Macdonald + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _M68K_TRAPS_H +#define _M68K_TRAPS_H + +typedef void (*e_vector)(void); + +extern e_vector vectors[]; + +#define VEC_BUSERR (2) +#define VEC_ADDRERR (3) +#define VEC_ILLEGAL (4) +#define VEC_ZERODIV (5) +#define VEC_CHK (6) +#define VEC_TRAP (7) +#define VEC_PRIV (8) +#define VEC_TRACE (9) +#define VEC_LINE10 (10) +#define VEC_LINE11 (11) +#define VEC_RESV1 (12) +#define VEC_COPROC (13) +#define VEC_FORMAT (14) +#define VEC_UNINT (15) +#define VEC_SPUR (24) +#define VEC_INT1 (25) +#define VEC_INT2 (26) +#define VEC_INT3 (27) +#define VEC_INT4 (28) +#define VEC_INT5 (29) +#define VEC_INT6 (30) +#define VEC_INT7 (31) +#define VEC_SYS (32) +#define VEC_TRAP1 (33) +#define VEC_TRAP2 (34) +#define VEC_TRAP3 (35) +#define VEC_TRAP4 (36) +#define VEC_TRAP5 (37) +#define VEC_TRAP6 (38) +#define VEC_TRAP7 (39) +#define VEC_TRAP8 (40) +#define VEC_TRAP9 (41) +#define VEC_TRAP10 (42) +#define VEC_TRAP11 (43) +#define VEC_TRAP12 (44) +#define VEC_TRAP13 (45) +#define VEC_TRAP14 (46) +#define VEC_TRAP15 (47) +#define VEC_FPBRUC (48) +#define VEC_FPIR (49) +#define VEC_FPDIVZ (50) +#define VEC_FPUNDER (51) +#define VEC_FPOE (52) +#define VEC_FPOVER (53) +#define VEC_FPNAN (54) +#define VEC_FPUNSUP (55) +#define VEC_UNIMPEA (60) +#define VEC_UNIMPII (61) + +#define VECOFF(vec) ((vec)<<2) + +/* Status register bits */ +#define PS_T (0x8000) +#define PS_S (0x2000) +#define PS_M (0x1000) +#define PS_C (0x0001) + +/* bits for 68020/68030 special status word */ + +#define FC (0x8000) +#define FB (0x4000) +#define RC (0x2000) +#define RB (0x1000) +#define DF (0x0100) +#define RM (0x0080) +#define RW (0x0040) +#define SZ (0x0030) +#define DFC (0x0007) + +/* bits for 68030 MMU status register (mmusr,psr) */ + +#define MMU_B (0x8000) /* bus error */ +#define MMU_L (0x4000) /* limit violation */ +#define MMU_S (0x2000) /* supervisor violation */ +#define MMU_WP (0x0800) /* write-protected */ +#define MMU_I (0x0400) /* invalid descriptor */ +#define MMU_M (0x0200) /* ATC entry modified */ +#define MMU_T (0x0040) /* transparent translation */ +#define MMU_NUM (0x0007) /* number of levels traversed */ + + +/* bits for 68040 special status word */ +#define CP_040 (0x8000) +#define CU_040 (0x4000) +#define CT_040 (0x2000) +#define CM_040 (0x1000) +#define MA_040 (0x0800) +#define ATC_040 (0x0400) +#define LK_040 (0x0200) +#define RW_040 (0x0100) +#define SIZ_040 (0x0060) +#define TT_040 (0x0018) +#define TM_040 (0x0007) + +/* bits for 68040 write back status word */ +#define WBV_040 (0x80) +#define WBSIZ_040 (0x60) +#define WBBYT_040 (0x20) +#define WBWRD_040 (0x40) +#define WBLNG_040 (0x00) +#define WBTT_040 (0x18) +#define WBTM_040 (0x07) + +/* bus access size codes */ +#define BA_SIZE_BYTE (0x20) +#define BA_SIZE_WORD (0x40) +#define BA_SIZE_LONG (0x00) +#define BA_SIZE_LINE (0x60) + +/* bus access transfer type codes */ +#define BA_TT_MOVE16 (0x08) + +/* bits for 68040 MMU status register (mmusr) */ +#define MMU_B_040 (0x0800) +#define MMU_G_040 (0x0400) +#define MMU_S_040 (0x0080) +#define MMU_CM_040 (0x0060) +#define MMU_M_040 (0x0010) +#define MMU_WP_040 (0x0004) +#define MMU_T_040 (0x0002) +#define MMU_R_040 (0x0001) + +/* bits in the 68060 fault status long word (FSLW) */ +#define MMU060_MA (0x08000000) /* misaligned */ +#define MMU060_LK (0x02000000) /* locked transfer */ +#define MMU060_RW (0x01800000) /* read/write */ +# define MMU060_RW_W (0x00800000) /* write */ +# define MMU060_RW_R (0x01000000) /* read */ +# define MMU060_RW_RMW (0x01800000) /* read/modify/write */ +# define MMU060_W (0x00800000) /* general write, includes rmw */ +#define MMU060_SIZ (0x00600000) /* transfer size */ +#define MMU060_TT (0x00180000) /* transfer type (TT) bits */ +#define MMU060_TM (0x00070000) /* transfer modifier (TM) bits */ +#define MMU060_IO (0x00008000) /* instruction or operand */ +#define MMU060_PBE (0x00004000) /* push buffer bus error */ +#define MMU060_SBE (0x00002000) /* store buffer bus error */ +#define MMU060_PTA (0x00001000) /* pointer A fault */ +#define MMU060_PTB (0x00000800) /* pointer B fault */ +#define MMU060_IL (0x00000400) /* double indirect descr fault */ +#define MMU060_PF (0x00000200) /* page fault (invalid descr) */ +#define MMU060_SP (0x00000100) /* supervisor protection */ +#define MMU060_WP (0x00000080) /* write protection */ +#define MMU060_TWE (0x00000040) /* bus error on table search */ +#define MMU060_RE (0x00000020) /* bus error on read */ +#define MMU060_WE (0x00000010) /* bus error on write */ +#define MMU060_TTR (0x00000008) /* error caused by TTR translation */ +#define MMU060_BPE (0x00000004) /* branch prediction error */ +#define MMU060_SEE (0x00000001) /* software emulated error */ + +/* cases of missing or invalid descriptors */ +#define MMU060_DESC_ERR (MMU060_TWE | MMU060_PTA | MMU060_PTB | \ + MMU060_IL | MMU060_PF) +/* bits that indicate real errors */ +#define MMU060_ERR_BITS (MMU060_PBE | MMU060_SBE | MMU060_DESC_ERR | \ + MMU060_SP | MMU060_WP | MMU060_RE | \ + MMU060_WE) + +/* structure for stack frames */ + +struct frame { + struct pt_regs ptregs; + union { + struct { + unsigned long iaddr; /* instruction address */ + } fmt2; + struct { + unsigned long effaddr; /* effective address */ + } fmt3; + struct { + unsigned long effaddr; /* effective address */ + unsigned long pc; /* pc of faulted instr */ + } fmt4; + struct { + unsigned long effaddr; /* effective address */ + unsigned short ssw; /* special status word */ + unsigned short wb3s; /* write back 3 status */ + unsigned short wb2s; /* write back 2 status */ + unsigned short wb1s; /* write back 1 status */ + unsigned long faddr; /* fault address */ + unsigned long wb3a; /* write back 3 address */ + unsigned long wb3d; /* write back 3 data */ + unsigned long wb2a; /* write back 2 address */ + unsigned long wb2d; /* write back 2 data */ + unsigned long wb1a; /* write back 1 address */ + unsigned long wb1dpd0; /* write back 1 data/push data 0*/ + unsigned long pd1; /* push data 1*/ + unsigned long pd2; /* push data 2*/ + unsigned long pd3; /* push data 3*/ + } fmt7; + struct { + unsigned long iaddr; /* instruction address */ + unsigned short int1[4]; /* internal registers */ + } fmt9; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[2]; + } fmta; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[4]; + unsigned long baddr; /* stage B address */ + unsigned short int4[2]; + unsigned long dibuf; /* data cycle input buffer */ + unsigned short int5[3]; + unsigned ver : 4; /* stack frame version # */ + unsigned int6:12; + unsigned short int7[18]; + } fmtb; + } un; +}; + +#endif /* _M68K_TRAPS_H */ diff --git a/include/asm-m68k/types.h b/include/asm-m68k/types.h new file mode 100644 index 000000000..945edb982 --- /dev/null +++ b/include/asm-m68k/types.h @@ -0,0 +1,52 @@ +#ifndef _M68K_TYPES_H +#define _M68K_TYPES_H + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ + +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; + +#endif /* __KERNEL__ */ + +#endif /* _M68K_TYPES_H */ diff --git a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h new file mode 100644 index 000000000..50ff178cd --- /dev/null +++ b/include/asm-m68k/uaccess.h @@ -0,0 +1,799 @@ +#ifndef __M68K_UACCESS_H +#define __M68K_UACCESS_H + +/* + * User space memory access functions + */ +#include <linux/sched.h> +#include <asm/segment.h> + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* We let the MMU do all checking */ +#define access_ok(type,addr,size) 1 + +extern inline int verify_area(int type, const void * addr, unsigned long size) +{ + return access_ok(type,addr,size)?0:-EFAULT; +} + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ + +#define put_user(x, ptr) \ +({ \ + int __pu_err; \ + typeof(*(ptr)) __pu_val = (x); \ + switch (sizeof (*(ptr))) { \ + case 1: \ + __put_user_asm(__pu_err, __pu_val, ptr, b); \ + break; \ + case 2: \ + __put_user_asm(__pu_err, __pu_val, ptr, w); \ + break; \ + case 4: \ + __put_user_asm(__pu_err, __pu_val, ptr, l); \ + break; \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ +}) +#define __put_user(x, ptr) put_user(x, ptr) + +extern int __put_user_bad(void); + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ +#define __put_user_asm(err,x,ptr,bwl) \ +__asm__ __volatile__ \ + ("21:moves" #bwl " %2,%1\n" \ + "1:\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "2: movel %3,%0\n" \ + " jra 1b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 21b,2b\n" \ + " .long 1b,2b\n" \ + ".text" \ + : "=d"(err) \ + : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0)) + +#define get_user(x, ptr) \ +({ \ + int __gu_err; \ + typeof(*(ptr)) __gu_val; \ + switch (sizeof(*(ptr))) { \ + case 1: \ + __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \ + break; \ + case 2: \ + __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \ + break; \ + case 4: \ + __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \ + break; \ + default: \ + __gu_val = 0; \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + (x) = __gu_val; \ + __gu_err; \ +}) +#define __get_user(x, ptr) get_user(x, ptr) + +extern int __get_user_bad(void); + +#define __get_user_asm(err,x,ptr,bwl,reg) \ +__asm__ __volatile__ \ + ("1: moves" #bwl " %2,%1\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "3: movel %3,%0\n" \ + " sub" #bwl " %1,%1\n" \ + " jra 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".text" \ + : "=d"(err), reg(x) \ + : "m"(*(ptr)), "i" (-EFAULT), "0"(0)) + +static inline unsigned long +__generic_copy_from_user(void *to, const void *from, unsigned long n) +{ + unsigned long tmp; + __asm__ __volatile__ + (" tstl %2\n" + " jeq 2f\n" + "1: movesl (%1)+,%3\n" + " movel %3,(%0)+\n" + " subql #1,%2\n" + " jne 1b\n" + "2: movel %4,%2\n" + " bclr #1,%2\n" + " jeq 4f\n" + "3: movesw (%1)+,%3\n" + " movew %3,(%0)+\n" + "4: bclr #0,%2\n" + " jeq 6f\n" + "5: movesb (%1)+,%3\n" + " moveb %3,(%0)+\n" + "6:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "7: lsll #2,%2\n" + " addl %4,%2\n" + " jra 6b\n" + "8: addql #2,%2\n" + " jra 6b\n" + "9: addql #1,%2\n" + " jra 6b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,7b\n" + " .long 3b,8b\n" + " .long 5b,9b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) + : "r"(n & 3), "0"(to), "1"(from), "2"(n/4) + : "d0", "memory"); + return n; +} + +static inline unsigned long +__generic_copy_to_user(void *to, const void *from, unsigned long n) +{ + unsigned long tmp; + __asm__ __volatile__ + (" tstl %2\n" + " jeq 3f\n" + "1: movel (%1)+,%3\n" + "22:movesl %3,(%0)+\n" + "2: subql #1,%2\n" + " jne 1b\n" + "3: movel %4,%2\n" + " bclr #1,%2\n" + " jeq 4f\n" + " movew (%1)+,%3\n" + "24:movesw %3,(%0)+\n" + "4: bclr #0,%2\n" + " jeq 5f\n" + " moveb (%1)+,%3\n" + "25:movesb %3,(%0)+\n" + "5:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "6: lsll #2,%2\n" + " addl %4,%2\n" + " jra 5b\n" + "7: addql #2,%2\n" + " jra 5b\n" + "8: addql #1,%2\n" + " jra 5b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 22b,6b\n" + " .long 2b,6b\n" + " .long 24b,7b\n" + " .long 4b,7b\n" + " .long 25b,8b\n" + " .long 5b,8b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) + : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)); + return n; +} + +#define __copy_from_user_big(to, from, n, fixup, copy) \ + __asm__ __volatile__ \ + ("10: movesl (%1)+,%%d0\n" \ + " movel %%d0,(%0)+\n" \ + " subql #1,%2\n" \ + " jne 10b\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "11: lsll #2,%2\n" \ + fixup "\n" \ + " jra 12f\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 10b,11b\n" \ + ".text\n" \ + copy "\n" \ + ".text\n" \ + "12:" \ + : "=a"(to), "=a"(from), "=d"(n) \ + : "0"(to), "1"(from), "2"(n/4) \ + : "d0", "memory") + +static inline unsigned long +__constant_copy_from_user(void *to, const void *from, unsigned long n) +{ + switch (n) { + case 0: + break; + case 1: + __asm__ __volatile__ + ("1: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #1,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 2: + __asm__ __volatile__ + ("1: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #2,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 3: + __asm__ __volatile__ + ("1: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + "2: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + "3:" + ".section .fixup,\"ax\"\n" + " .even\n" + "4: addql #2,%2\n" + "5: addql #1,%2\n" + " jra 3b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 2b,5b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 4: + __asm__ __volatile__ + ("1: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "2:" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #4,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 8: + __asm__ __volatile__ + ("1: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "2: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "3:" + ".section .fixup,\"ax\"\n" + " .even\n" + "4: addql #4,%2\n" + "5: addql #4,%2\n" + " jra 3b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 2b,5b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 12: + __asm__ __volatile__ + ("1: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "2: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "3: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "4:" + ".section .fixup,\"ax\"\n" + " .even\n" + "5: addql #4,%2\n" + "6: addql #4,%2\n" + "7: addql #4,%2\n" + " jra 4b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,5b\n" + " .long 2b,6b\n" + " .long 3b,7b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 16: + __asm__ __volatile__ + ("1: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "2: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "3: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "4: movesl (%1)+,%%d0\n" + " movel %%d0,(%0)+\n" + "5:" + ".section .fixup,\"ax\"\n" + " .even\n" + "6: addql #4,%2\n" + "7: addql #4,%2\n" + "8: addql #4,%2\n" + "9: addql #4,%2\n" + " jra 5b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,6b\n" + " .long 2b,7b\n" + " .long 3b,8b\n" + " .long 4b,9b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + default: + switch (n & 3) { + case 0: + __copy_from_user_big(to, from, n, "", ""); + break; + case 1: + __copy_from_user_big(to, from, n, + /* fixup */ + "1: addql #1,%2", + /* copy */ + "2: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + ".section __ex_table,\"a\"\n" + " .long 2b,1b"); + break; + case 2: + __copy_from_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2", + /* copy */ + "2: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + ".section __ex_table,\"a\"\n" + " .long 2b,1b"); + break; + case 3: + __copy_from_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2" + "2: addql #1,%2", + /* copy */ + "3: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + "4: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + ".section __ex_table,\"a\"\n" + " .long 3b,1b\n" + " .long 4b,2b"); + break; + } + break; + } + return n; +} + +#define __copy_to_user_big(to, from, n, fixup, copy) \ + __asm__ __volatile__ \ + ("10: movel (%1)+,%%d0\n" \ + "31: movesl %%d0,(%0)+\n" \ + "11: subql #1,%2\n" \ + " jne 10b\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "12: lsll #2,%2\n" \ + fixup "\n" \ + " jra 13f\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 31b,12b\n" \ + " .long 11b,12b\n" \ + ".text\n" \ + copy "\n" \ + ".text\n" \ + "13:" \ + : "=a"(to), "=a"(from), "=d"(n) \ + : "0"(to), "1"(from), "2"(n/4) \ + : "d0") + +static inline unsigned long +__constant_copy_to_user(void *to, const void *from, unsigned long n) +{ + switch (n) { + case 0: + break; + case 1: + __asm__ __volatile__ + (" moveb (%1)+,%%d0\n" + "21:movesb %%d0,(%0)+\n" + "1:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "2: addql #1,%2\n" + " jra 1b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n " + " .long 21b,2b\n" + " .long 1b,2b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 2: + __asm__ __volatile__ + (" movew (%1)+,%%d0\n" + "21:movesw %%d0,(%0)+\n" + "1:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "2: addql #2,%2\n" + " jra 1b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,2b\n" + " .long 1b,2b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 3: + __asm__ __volatile__ + (" movew (%1)+,%%d0\n" + "21:movesw %%d0,(%0)+\n" + "1: moveb (%1)+,%%d0\n" + "22:movesb %%d0,(%0)+\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #2,%2\n" + "4: addql #1,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,3b\n" + " .long 1b,3b\n" + " .long 22b,4b\n" + " .long 2b,4b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 4: + __asm__ __volatile__ + (" movel (%1)+,%%d0\n" + "21:movesl %%d0,(%0)+\n" + "1:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "2: addql #4,%2\n" + " jra 1b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,2b\n" + " .long 1b,2b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 8: + __asm__ __volatile__ + (" movel (%1)+,%%d0\n" + "21:movesl %%d0,(%0)+\n" + "1: movel (%1)+,%%d0\n" + "22:movesl %%d0,(%0)+\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: addql #4,%2\n" + "4: addql #4,%2\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,3b\n" + " .long 1b,3b\n" + " .long 22b,4b\n" + " .long 2b,4b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 12: + __asm__ __volatile__ + (" movel (%1)+,%%d0\n" + "21:movesl %%d0,(%0)+\n" + "1: movel (%1)+,%%d0\n" + "22:movesl %%d0,(%0)+\n" + "2: movel (%1)+,%%d0\n" + "23:movesl %%d0,(%0)+\n" + "3:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "4: addql #4,%2\n" + "5: addql #4,%2\n" + "6: addql #4,%2\n" + " jra 3b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,4b\n" + " .long 1b,4b\n" + " .long 22b,5b\n" + " .long 2b,5b\n" + " .long 23b,6b\n" + " .long 3b,6b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + case 16: + __asm__ __volatile__ + (" movel (%1)+,%%d0\n" + "21:movesl %%d0,(%0)+\n" + "1: movel (%1)+,%%d0\n" + "22:movesl %%d0,(%0)+\n" + "2: movel (%1)+,%%d0\n" + "23:movesl %%d0,(%0)+\n" + "3: movel (%1)+,%%d0\n" + "24:movesl %%d0,(%0)+\n" + "4:" + ".section .fixup,\"ax\"\n" + " .even\n" + "5: addql #4,%2\n" + "6: addql #4,%2\n" + "7: addql #4,%2\n" + "8: addql #4,%2\n" + " jra 4b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,5b\n" + " .long 1b,5b\n" + " .long 22b,6b\n" + " .long 2b,6b\n" + " .long 23b,7b\n" + " .long 3b,7b\n" + " .long 24b,8b\n" + " .long 4b,8b\n" + ".text" + : "=a"(to), "=a"(from), "=d"(n) + : "0"(to), "1"(from), "2"(0) + : "d0", "memory"); + break; + default: + switch (n & 3) { + case 0: + __copy_to_user_big(to, from, n, "", ""); + break; + case 1: + __copy_to_user_big(to, from, n, + /* fixup */ + "1: addql #1,%2", + /* copy */ + " moveb (%1)+,%%d0\n" + "22:movesb %%d0,(%0)+\n" + "2:" + ".section __ex_table,\"a\"\n" + " .long 22b,1b\n" + " .long 2b,1b"); + break; + case 2: + __copy_to_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2", + /* copy */ + " movew (%1)+,%%d0\n" + "22:movesw %%d0,(%0)+\n" + "2:" + ".section __ex_table,\"a\"\n" + " .long 22b,1b\n" + " .long 2b,1b"); + break; + case 3: + __copy_to_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2" + "2: addql #1,%2", + /* copy */ + " movew (%1)+,%%d0\n" + "23:movesw %%d0,(%0)+\n" + "3: moveb (%1)+,%%d0\n" + "24:movesb %%d0,(%0)+\n" + "4:" + ".section __ex_table,\"a\"\n" + " .long 23b,1b\n" + " .long 3b,1b\n" + " .long 24b,2b\n" + " .long 4b,2b"); + break; + } + break; + } + return n; +} + +#define copy_from_user(to, from, n) \ +(__builtin_constant_p(n) ? \ + __constant_copy_from_user(to, from, n) : \ + __generic_copy_from_user(to, from, n)) + +#define copy_to_user(to, from, n) \ +(__builtin_constant_p(n) ? \ + __constant_copy_to_user(to, from, n) : \ + __generic_copy_to_user(to, from, n)) + +/* + * Copy a null terminated string from userspace. + */ + +static inline long +strncpy_from_user(char *dst, const char *src, long count) +{ + long res; + if (count == 0) return count; + __asm__ __volatile__ + ("1: movesb (%2)+,%%d0\n" + "12:moveb %%d0,(%1)+\n" + " jeq 2f\n" + " subql #1,%3\n" + " jne 1b\n" + "2: subl %3,%0\n" + "3:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "4: movel %4,%0\n" + " jra 3b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 12b,4b\n" + ".text" + : "=d"(res), "=a"(dst), "=a"(src), "=d"(count) + : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count) + : "d0", "memory"); + return res; +} + +/* + * Return the size of a string (including the ending 0) + * + * Return 0 for error + */ +static inline long strlen_user(const char * src) +{ + long res = (long) src; + __asm__ __volatile__ + ("1: movesb (%1)+,%%d0\n" + "12:tstb %%d0\n" + " jne 1b\n" + " subl %1,%0\n" + " negl %0\n" + "2:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "3: moveq %2,%0\n" + " jra 2b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + " .long 12b,3b\n" + ".text" + : "=d"(res), "=a"(src) + : "i"(0), "0"(res), "1"(src) + : "d0", "memory"); + return res; +} + +/* + * Zero Userspace + */ + +static inline unsigned long +clear_user(void *to, unsigned long n) +{ + __asm__ __volatile__ + (" tstl %1\n" + " jeq 3f\n" + "1: movesl %3,(%0)+\n" + "2: subql #1,%1\n" + " jne 1b\n" + "3: movel %2,%1\n" + " bclr #1,%1\n" + " jeq 4f\n" + "24:movesw %3,(%0)+\n" + "4: bclr #0,%1\n" + " jeq 5f\n" + "25:movesb %3,(%0)+\n" + "5:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "6: lsll #2,%1\n" + " addl %2,%1\n" + " jra 5b\n" + "7: addql #2,%1\n" + " jra 5b\n" + "8: addql #1,%1\n" + " jra 5b\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,6b\n" + " .long 2b,6b\n" + " .long 24b,7b\n" + " .long 4b,7b\n" + " .long 25b,8b\n" + " .long 5b,8b\n" + ".text" + : "=a"(to), "=d"(n) + : "r"(n & 3), "r"(0), "0"(to), "1"(n/4)); + return n; +} + +#endif /* _M68K_UACCESS_H */ diff --git a/include/asm-m68k/unaligned.h b/include/asm-m68k/unaligned.h new file mode 100644 index 000000000..479f15864 --- /dev/null +++ b/include/asm-m68k/unaligned.h @@ -0,0 +1,16 @@ +#ifndef __M68K_UNALIGNED_H +#define __M68K_UNALIGNED_H + +/* + * The m68k can do unaligned accesses itself. + * + * The strange macros are there to make sure these can't + * be misused in a way that makes them not work on other + * architectures where unaligned accesses aren't as simple. + */ + +#define get_unaligned(ptr) (*(ptr)) + +#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) + +#endif diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h index acad643bf..b55f296a7 100644 --- a/include/asm-m68k/unistd.h +++ b/include/asm-m68k/unistd.h @@ -1,114 +1,344 @@ #ifndef _ASM_M68K_UNISTD_H_ #define _ASM_M68K_UNISTD_H_ -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +/* + * This file contains the system call numbers. + */ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl /* 110 */ not supported +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86 /* 113 */ not supported +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 + +/* user-visible error numbers are in the range -1 - -122: see + <asm-m68k/errno.h> */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + #define _syscall0(type,name) \ type name(void) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ +register long __res __asm__ ("%d0") = __NR_##name; \ __asm__ __volatile__ ("trap #0" \ : "=g" (__res) \ - : "0" (__NR_##name) \ - : "d0"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ + : "0" (__res) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall1(type,name,atype,a) \ type name(atype a) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)) \ - : "d0", "d1"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall2(type,name,atype,a,btype,b) \ type name(atype a,btype b) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "movel %3,d2\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)), \ - "g" ((long)(b)) \ - : "d0", "d1", "d2"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a), "d" (__b) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall3(type,name,atype,a,btype,b,ctype,c) \ type name(atype a,btype b,ctype c) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "movel %3,d2\n\t" \ - "movel %4,d3\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)), \ - "g" ((long)(b)), \ - "g" ((long)(c)) \ - : "d0", "d1", "d2", "d3"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ type name (atype a, btype b, ctype c, dtype d) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "movel %3,d2\n\t" \ - "movel %4,d3\n\t" \ - "movel %5,d4\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)), \ - "g" ((long)(b)), \ - "g" ((long)(c)), \ - "g" ((long)(d)) \ - : "d0", "d1", "d2", "d3", "d4"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +register long __d __asm__ ("%d4") = (long)(d); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d) \ + : "%d0"); \ +__syscall_return(type,__res); \ } #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ type name (atype a,btype b,ctype c,dtype d,etype e) \ { \ -register long __res __asm__ ("d0") = __NR_##name; \ -__asm__ __volatile__ ("movel %2,d1\n\t" \ - "movel %3,d2\n\t" \ - "movel %4,d3\n\t" \ - "movel %5,d4\n\t" \ - "movel %6,d5\n\t" \ - "trap #0" \ - : "=g" (__res) \ - : "0" (__NR_##name), "g" ((long)(a)), \ - "g" ((long)(b)), \ - "g" ((long)(c)), \ - "g" ((long)(d)), \ - "g" ((long)(e)) \ - : "d0", "d1", "d2", "d3", "d4", "d5"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +register long __c __asm__ ("%d3") = (long)(c); \ +register long __d __asm__ ("%d4") = (long)(d); \ +register long __e __asm__ ("%d5") = (long)(e); \ +__asm__ __volatile__ ("trap #0" \ + : "=d" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d), "d" (__e) \ + : "%d0"); \ +__syscall_return(type,__res); \ +} + +#ifdef __KERNEL_SYSCALLS__ + +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ +#define __NR__exit __NR_exit +static inline _syscall0(int,idle) +static inline _syscall0(int,fork) +static inline _syscall2(int,clone,unsigned long,flags,char *,usp) +static inline _syscall0(int,pause) +static inline _syscall0(int,setup) +static inline _syscall0(int,sync) +static inline _syscall0(pid_t,setsid) +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static inline _syscall1(int,dup,int,fd) +static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static inline _syscall3(int,open,const char *,file,int,flag,int,mode) +static inline _syscall1(int,close,int,fd) +static inline _syscall1(int,_exit,int,exitcode) +static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +/* + * 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. + */ +static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + register long retval __asm__ ("d0") = __NR_clone; + register long clone_arg __asm__ ("d1") = flags | CLONE_VM; + unsigned long fs; + + fs = get_fs(); + set_fs (KERNEL_DS); + + __asm__ __volatile__ + ("trap #0\n\t" /* Linux/m68k system call */ + "tstl %0\n\t" /* child or parent */ + "jne 1f\n\t" /* parent - jump */ + "movel %3,%%sp@-\n\t" /* push argument */ + "jsr %4@\n\t" /* call fn */ + "movel %0,%%d1\n\t" /* pass exit value */ + "movel %2,%0\n\t" /* exit */ + "trap #0\n" + "1:" + : "=d" (retval) + : "0" (__NR_clone), "i" (__NR_exit), + "r" (arg), "a" (fn), "d" (clone_arg) + : "d0"); + + set_fs (fs); + return retval; } +static inline pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +#endif + #endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/include/asm-m68k/user.h b/include/asm-m68k/user.h new file mode 100644 index 000000000..126e23548 --- /dev/null +++ b/include/asm-m68k/user.h @@ -0,0 +1,88 @@ +#ifndef _M68K_USER_H +#define _M68K_USER_H + +#include <asm/page.h> +#include <linux/ptrace.h> +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ + +struct user_m68kfp_struct { + unsigned long fpregs[8*3]; /* fp0-fp7 registers */ + unsigned long fpcntl[3]; /* fp control regs */ +}; + +/* This is the old layout of "struct pt_regs" as of Linux 1.x, and + is still the layout used by user (the new pt_regs doesn't have + all registers). */ +struct user_regs_struct { + long d1,d2,d3,d4,d5,d6,d7; + long a0,a1,a2,a3,a4,a5,a6; + long d0; + long usp; + long orig_d0; + short stkadj; + short sr; + long pc; + short fmtvec; + short __fill; +}; + + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ +struct user{ +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + struct user_regs_struct regs; /* Where the registers are actually stored */ +/* ptrace does not yet supply these. Someday.... */ + int u_fpvalid; /* True if math co-processor being used. */ + /* for this mess. Not yet used. */ + struct user_m68kfp_struct m68kfp; /* Math Co-processor registers. */ +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ + /* the registers. */ + struct user_m68kfp_struct* u_fpstate; /* Math Co-processor pointer. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ +}; +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif diff --git a/include/asm-m68k/zorro.h b/include/asm-m68k/zorro.h new file mode 100644 index 000000000..adfc4617c --- /dev/null +++ b/include/asm-m68k/zorro.h @@ -0,0 +1,574 @@ +/* + * asm-m68k/zorro.h -- Amiga AutoConfig (Zorro) Expansion Device Definitions + * + * Copyright (C) 1995 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_M68K_ZORRO_H_ +#define _ASM_M68K_ZORRO_H_ + +#ifndef __ASSEMBLY__ + +#include <linux/config.h> +#include <asm/amigatypes.h> + + +/* + * Defined Board Manufacturers + * + * Please update arch/m68k/amiga/zorro.c if you make changes here + * Many IDs were obtained from ExpName/Identify ((C) Richard Körber) + * and by looking at the NetBSD-Amiga kernel sources + */ + +#define MANUF_PACIFIC (0x00D3) /* Pacific Peripherals */ +#define PROD_SE_2000_A500 (0x00) /* SE 2000 A500 */ +#define PROD_PACIFIC_HD (0x0A) /* HD Controller */ + +#define MANUF_KUPKE (0x00DD) /* Kupke */ +#define PROD_GOLEM_BOX_2 (0x00) /* Golem RAM Box 2MB */ + +#define MANUF_MEMPHIS (0x0100) /* Memphis */ +#define PROD_STORMBRINGER (0x00) /* Stormbringer */ + +#define MANUF_COMMODORE2 (0x0201) /* Commodore Braunschweig */ +#define PROD_A2088 (0x01) /* CBM A2088 XT Bridgeboard */ +#define PROD_A2286 (0x02) /* CBM A2286 AT Bridgeboard */ +#define PROD_A4091_2 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2386SX (0x67) /* CBM A2386-SX Bridgeboard */ + +#define MANUF_COMMODORE (0x0202) /* Commodore West Chester */ +#define PROD_A2090A (0x01) /* CBM A2090/A2090A HD Controller */ +#define PROD_A590 (0x02) /* CBM A590 SCSI Controller */ +#define PROD_A2091 (0x03) /* CBM A2091 SCSI Controller */ +#define PROD_A2090B (0x04) /* CBM A2090B 2090 Autoboot Card */ +#define PROD_ARCNET (0x09) /* CBM A2060 Arcnet Card */ +#define PROD_CBMRAM (0x0A) /* CBM A2052/58.RAM | 590/2091.RAM */ +#define PROD_A560RAM (0x20) /* CBM A560 Memory Module */ +#define PROD_A2232PROTO (0x45) /* CBM A2232 Serial Prototype */ +#define PROD_A2232 (0x46) /* CBM A2232 Serial Production */ +#define PROD_A2620 (0x50) /* CBM A2620 68020/RAM Card */ +#define PROD_A2630 (0x51) /* CBM A2630 68030/RAM Card */ +#define PROD_A4091 (0x54) /* CBM A4091 SCSI Controller */ +#define PROD_A2065_2 (0x5A) /* A2065 Ethernet Card */ +#define PROD_ROMULATOR (0x60) /* CBM Romulator Card */ +#define PROD_A3000TESTFIX (0x61) /* CBM A3000 Test Fixture */ +#define PROD_A2386SX_2 (0x67) /* A2386-SX Bridgeboard */ +#define PROD_A2065 (0x70) /* CBM A2065 Ethernet Card */ + +#define MANUF_COMMODORE3 (0x0203) /* Commodore West Chester */ +#define PROD_A2090A_CM (0x03) /* A2090A Combitec/MacroSystem */ + +#define MANUF_KCS (0x02FF) /* Kolff Computer Supplies */ +#define PROD_POWER_BOARD (0x00) /* KCS Power PC Board */ + +#define MANUF_CARDCO (0x03EC) /* Cardco */ +#define PROD_KRONOS_2000_SCSI (0x04) /* Kronos 2000 SCSI Controller */ +#define PROD_A1000_SCSI (0x0C) /* A1000 SCSI Controller */ +#define PROD_ESCORT_SCSI (0x0E) /* Escort SCSI Controller */ +#define PROD_CC_A2410 (0xF5) /* Cardco A2410 Hires Graphics Card */ + +#define MANUF_A_SQUARED (0x03ED) /* A-Squared */ +#define PROD_LIVE_2000 (0x01) /* Live! 2000 */ + +#define MANUF_COMSPEC (0x03EE) /* ComSpec Communications */ +#define PROD_AX2000 (0x01) /* AX2000 */ + +#define MANUF_ANAKIN (0x03F1) /* Anakin */ +#define PROD_EASYL (0x01) /* Easyl Tablet */ + +#define MANUF_MICROBOTICS (0x03F2) /* MicroBotics */ +#define PROD_STARBOARD_II (0x00) /* StarBoard II */ +#define PROD_STARDRIVE (0x02) /* StarDrive */ +#define PROD_8_UP_A (0x03) /* 8-Up (Rev A) */ +#define PROD_8_UP_Z (0x04) /* 8-Up (Rev Z) */ +#define PROD_VXL_RAM (0x44) /* VXL RAM */ +#define PROD_VXL_30 (0x45) /* VXL-30 Turbo Board */ +#define PROD_MBX_1200 (0x81) /* MBX 1200 */ +#define PROD_HARDFRAME_2000 (0x9E) /* Hardframe 2000 */ +#define PROD_MBX_1200_2 (0xC1) /* MBX 1200 */ + +#define MANUF_ACCESS (0x03F4) /* Access Associates */ + +#define MANUF_EXPANSION_TECH (0x03F6) /* Expansion Technologies */ + +#define MANUF_ASDG (0x03FF) /* ASDG */ +#define PROD_ASDG_MEMORY (0x01) /* Memory Expansion */ +#define PROD_ASDG_MEMORY_2 (0x02) /* Memory Expansion */ +#define PROD_LAN_ROVER (0xFE) /* Lan Rover Ethernet */ +#define PROD_TWIN_X (0xFF) /* Twin-X Serial Card */ + +#define MANUF_IMTRONICS (0x0404) /* Imtronics */ +#define PROD_HURRICANE_2800 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_2 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_UNIV_OF_LOWELL (0x0406) /* University of Lowell */ +#define PROD_A2410 (0x00) /* CBM A2410 Hires Graphics Card */ + +#define MANUF_AMERISTAR (0x041D) /* Ameristar */ +#define PROD_AMERISTAR2065 (0x01) /* A2065 Ethernet Card */ +#define PROD_A560 (0x09) /* Arcnet Card */ +#define PROD_A4066 (0x0A) /* A4066 Ethernet Card */ + +#define MANUF_SUPRA (0x0420) /* Supra */ +#define PROD_SUPRADRIVE_4x4 (0x01) /* SupraDrive 4x4 SCSI Controller */ +#define PROD_SUPRA_2000 (0x03) /* 2000 DMA HD */ +#define PROD_SUPRA_500 (0x05) /* 500 HD/RAM */ +#define PROD_SUPRA_500RX (0x09) /* 500RX/2000 RAM */ +#define PROD_SUPRA_500RX_2 (0x0A) /* 500RX/2000 RAM */ +#define PROD_SUPRA_2400ZI (0x0B) /* 2400zi Modem */ +#define PROD_WORDSYNC (0x0C) /* Supra Wordsync SCSI Controller */ +#define PROD_WORDSYNC_II (0x0D) /* Supra Wordsync II SCSI Controller */ +#define PROD_SUPRA_2400ZIPLUS (0x10) /* 2400zi+ Modem */ + +#define MANUF_CSA (0x0422) /* CSA */ +#define PROD_MAGNUM (0x11) /* Magnum 40 SCSI Controller */ +#define PROD_12GAUGE (0x15) /* 12 Gauge SCSI Controller */ + +#define MANUF_GVP3 (0x06E1) /* Great Valley Products */ +#define PROD_IMPACT (0x08) /* Impact SCSI/Memory */ + +#define MANUF_BYTEBOX (0x07DA) /* ByteBox */ +#define PROD_BYTEBOX_A500 (0x00) /* A500 */ + +#define MANUF_HACKER (0x07DB) /* Test only: no product definitions */ + +#define MANUF_POWER_COMPUTING (0x07DC) /* Power Computing (DKB) */ +#define PROD_DKB_3128 (0x0E) /* DKB 3128 RAM */ +#define PROD_VIPER_II_COBRA (0x12) /* Viper II Turbo Board (DKB Cobra) */ + +#define MANUF_GVP (0x07E1) /* Great Valley Products */ +#define PROD_IMPACT_I_4K (0x01) /* Impact Series-I SCSI 4K */ +#define PROD_IMPACT_I_16K_2 (0x02) /* Impact Series-I SCSI 16K/2 */ +#define PROD_IMPACT_I_16K_3 (0x03) /* Impact Series-I SCSI 16K/3 */ +#define PROD_IMPACT_3001_IDE (0x08) /* Impact 3001 IDE */ +#define PROD_IMPACT_3001_RAM (0x09) /* Impact 3001 RAM */ +#define PROD_GVPIISCSI (0x0B) /* GVP Series II SCSI Controller */ +#define PROD_GVPIISCSI_2 (0x09) /* evidence that the driver works + for this product code also */ +#define PROD_GVPIIRAM (0x0A) /* GVP Series II RAM */ +#define PROD_GVP (0x0B) /* This code is used by a wide range of + GVP products - use the epc to + identify it correctly */ +#define PROD_GVP_A2000_030 (0x0D) /* GVP A2000 68030 Turbo Board */ +#define PROD_IMPACT_3001_IDE_2 (0x0D) /* Impact 3001 IDE */ +#define PROD_GFORCE_040_SCSI (0x16) /* GForce 040 with SCSI (new) */ +#define PROD_GVPIV_24 (0x20) /* GVP IV-24 Graphics Board */ +#define PROD_GFORCE_040 (0xFF) /* GForce 040 Turbo Board */ +/* #define PROD_GVPIO_EXT (0xFF)*/ /* GVP I/O Extender */ + +#define MANUF_SYNERGY (0x07E5) /* Synergy */ + +#define MANUF_XETEC (0x07E6) /* Xetec */ +#define PROD_FASTCARD_SCSI (0x01) /* FastCard SCSI Controller */ +#define PROD_FASTCARD_RAM (0x02) /* FastCard RAM */ + +#define MANUF_PPI (0x07EA) /* Progressive Peripherals Inc. */ +#define PROD_MERCURY (0x00) /* Mercury Turbo Board */ +#define PROD_PPS_A3000_040 (0x01) /* PP&S A3000 68040 Turbo Board */ +#define PROD_PPS_A2000_040 (0x69) /* PP&S A2000 68040 Turbo Board */ +#define PROD_ZEUS (0x96) /* Zeus SCSI Controller */ +#define PROD_PPS_A500_040 (0xBB) /* PP&S A500 68040 Turbo Board */ + +#define MANUF_XEBEC (0x07EC) /* Xebec */ + +#define MANUF_SPIRIT (0x07F2) /* Spirit */ +#define PROD_HDA_506 (0x04) /* HDA 506 Harddisk */ +#define PROD_OCTABYTE_RAM (0x06) /* OctaByte RAM */ + +#define MANUF_BSC (0x07FE) /* BSC */ +#define PROD_ALF_3_SCSI (0x03) /* BSC ALF 3 SCSI Controller */ + +#define MANUF_BSC3 (0x0801) /* BSC */ +#define PROD_ALF_2_SCSI (0x01) /* ALF 2 SCSI Controller */ +#define PROD_ALF_3_SCSI_2 (0x03) /* ALF 3 SCSI Controller */ + +#define MANUF_C_LTD (0x0802) /* C Ltd. */ +#define PROD_KRONOS_SCSI (0x04) /* Kronos SCSI Controller */ +#define PROD_A1000_SCSI_2 (0x0C) /* A1000 SCSI Controller */ + +#define MANUF_JOCHHEIM (0x0804) /* Jochheim */ +#define PROD_JOCHHEIM_RAM (0x01) /* Jochheim RAM */ + +#define MANUF_CHECKPOINT (0x0807) /* Checkpoint Technologies */ +#define PROD_SERIAL_SOLUTION (0x00) /* Serial Solution */ + +#define MANUF_ICD (0x0817) /* ICD */ +#define PROD_ADVANTAGE_2000 (0x01) /* Advantage 2000 SCSI Controller */ + +#define MANUF_KUPKE2 (0x0819) /* Kupke */ +#define PROD_KUPKE_SCSI_II (0x02) /* Golem SCSI-II Controller */ +#define PROD_GOLEM_BOX (0x03) /* Golem Box */ +#define PROD_KUPKE_SCSI_AT (0x05) /* SCSI/AT Controller */ + +#define MANUF_HARDITAL (0x0820) /* Hardital Synthesis */ +#define PROD_TQM (0x14) /* TQM 68030+68882 Turbo Board */ + +#define MANUF_BSC2 (0x082C) /* BSC */ +#define PROD_OKTAGON_SCSI (0x05) /* BSC Oktagon 2008 SCSI Controller */ +#define PROD_TANDEM (0x06) /* BSC Tandem AT-2008/508 IDE */ +#define PROD_OKTAGON_RAM (0x08) /* BSC Oktagon 2008 RAM */ +#define PROD_MULTIFACE_I (0x10) /* Alfa Data MultiFace I */ +#define PROD_MULTIFACE_II (0x11) /* Alfa Data MultiFace II */ +#define PROD_MULTIFACE_III (0x12) /* Alfa Data MultiFace III */ +#define PROD_ISDN_MASTERCARD (0x40) /* BSC ISDN MasterCard */ +#define PROD_ISDN_MASTERCARD_2 (0x41) /* BSC ISDN MasterCard II */ + +#define MANUF_ADV_SYS_SOFT (0x0836) /* Advanced Systems & Software */ +#define PROD_NEXUS_SCSI (0x01) /* Nexus SCSI Controller */ +#define PROD_NEXUS_RAM (0x08) /* Nexus RAM */ + +#define MANUF_IMPULSE (0x0838) /* Impulse */ +#define PROD_FIRECRACKER_24 (0x00) /* FireCracker 24 */ + +#define MANUF_IVS (0x0840) /* IVS */ +#define PROD_GRANDSLAM (0x04) /* GrandSlam RAM */ +#define PROD_IVS_OVERDRIVE (0x10) /* OverDrive HD */ +#define PROD_TRUMPCARD_CLASSIC (0x30) /* Trumpcard Classic SCSI Controller */ +#define PROD_TRUMPCARD_PRO (0x34) /* Trumpcard Pro SCSI Controller */ +#define PROD_META_4 (0x40) /* Meta-4 RAM */ +#define PROD_VECTOR (0xF3) /* Vector SCSI Controller */ + +#define MANUF_VECTOR (0x0841) /* Vector */ +#define PROD_CONNECTION (0xE3) /* Connection Serial IO */ + +#define MANUF_XPERT_PRODEV (0x0845) /* XPert/ProDev */ +#define PROD_VISIONA_RAM (0x01) /* Visiona Graphics Board */ +#define PROD_VISIONA_REG (0x02) +#define PROD_MERLIN_RAM (0x03) /* Merlin Graphics Board */ +#define PROD_MERLIN_REG (0x04) + +#define MANUF_HYDRA_SYSTEMS (0x0849) /* Hydra Systems */ +#define PROD_AMIGANET (0x01) /* Amiganet Board */ + +#define MANUF_SUNRIZE (0x084F) /* Sunrize Industries */ +#define PROD_AD516 (0x02) /* AD516 Audio */ + +#define MANUF_TRICERATOPS (0x0850) /* Triceratops */ +#define PROD_TRICERATOPS (0x01) /* Triceratops Multi I/O Board */ + +#define MANUF_APPLIED_MAGIC (0x0851) /* Applied Magic Inc */ +#define PROD_DMI_RESOLVER (0x01) /* DMI Resolver Graphics Board */ +#define PROD_DIGITAL_BCASTER (0x06) /* Digital Broadcaster */ + +#define MANUF_GFX_BASE (0x085E) /* GFX-Base */ +#define PROD_GDA_1_RAM (0x00) /* GDA-1 Graphics Board */ +#define PROD_GDA_1_REG (0x01) + +#define MANUF_ROCTEC (0x0860) /* RocTec */ +#define PROD_RH_800C (0x01) /* RH 800C Hard Disk Controller */ +#define PROD_RH_800C_RAM (0x01) /* RH 800C RAM */ + +#define MANUF_HELFRICH1 (0x0861) /* Helfrich */ +#define PROD_RAINBOW3 (0x21) /* Rainbow3 Graphics Board */ + +#define MANUF_SW_RESULT_ENTS (0x0866) /* Software Result Enterprises */ +#define PROD_GG2PLUS (0x01) /* GG2+ Bus Converter */ + +#define MANUF_MASOBOSHI (0x086D) /* Masoboshi */ +#define PROD_MASTER_CARD_RAM (0x03) /* Master Card RAM */ +#define PROD_MASTER_CARD_SCSI (0x04) /* Master Card SCSI Controller */ +#define PROD_MVD_819 (0x07) /* MVD 819 */ + +#define MANUF_DELACOMP (0x0873) /* DelaComp */ +#define PROD_DELACOMP_RAM_2000 (0x01) /* RAM Expansion 2000 */ + +#define MANUF_VILLAGE_TRONIC (0x0877) /* Village Tronic */ +#define PROD_DOMINO_RAM (0x01) /* Domino Graphics Board (RAM) */ +#define PROD_DOMINO_REG (0x02) /* Domino Graphics Board (REG) */ +#define PROD_PICASSO_II_RAM (0x0B) /* Picasso II Graphics Board */ +#define PROD_PICASSO_II_REG (0x0C) +#define PROD_PICASSO_II_REG_2 (0x0D) +#define PROD_ARIADNE (0xC9) /* Ariadne Ethernet */ + +#define MANUF_UTILITIES_ULTD (0x087B) /* Utilities Unlimited */ +#define PROD_EMPLANT_DELUXE (0x15) /* Emplant Deluxe SCSI Controller */ +#define PROD_EMPLANT_DELUXE2 (0x20) /* Emplant Deluxe SCSI Controller */ + +#define MANUF_AMITRIX (0x0880) /* Amitrix */ +#define PROD_AMITRIX_MULTI_IO (0x01) /* Multi-IO */ +#define PROD_AMITRIX_CD_RAM (0x02) /* CD-RAM Memory */ + +#define MANUF_MTEC (0x0890) /* MTEC Germany */ +#define PROD_MTEC_68030 (0x03) /* 68030 Turbo Board */ +#define PROD_MTEC_T1230 (0x20) /* A1200 T68030/42 RTC Turbo Board */ +#define PROD_MTEC_RAM (0x22) /* MTEC 8MB RAM */ + +#define MANUF_GVP2 (0x0891) /* Great Valley Products */ +#define PROD_SPECTRUM_RAM (0x01) /* EGS 28/24 Spectrum Graphics Board */ +#define PROD_SPECTRUM_REG (0x02) + +#define MANUF_HELFRICH2 (0x0893) /* Helfrich */ +#define PROD_PICCOLO_RAM (0x05) /* Piccolo Graphics Board */ +#define PROD_PICCOLO_REG (0x06) +#define PROD_PEGGY_PLUS (0x07) /* PeggyPlus MPEG Decoder Board */ +#define PROD_VIDEOCRUNCHER (0x08) /* VideoCruncher */ +#define PROD_SD64_RAM (0x0A) /* SD64 Graphics Board */ +#define PROD_SD64_REG (0x0B) + +#define MANUF_MACROSYSTEMS (0x089B) /* MacroSystems USA */ +#define PROD_WARP_ENGINE (0x13) /* Warp Engine 40xx SCSI Controller */ + +#define MANUF_ELBOX (0x089E) /* ElBox Computer */ +#define PROD_ELBOX_1200 (0x06) /* Elbox 1200/4 RAM */ + +#define MANUF_HARMS_PROF (0x0A00) /* Harms Professional */ +#define PROD_HARMS_030_PLUS (0x10) /* 030 plus */ +#define PROD_3500_TURBO (0xD0) /* 3500 Turbo board */ + +#define MANUF_MICRONIK (0x0A50) /* Micronik */ +#define PROD_RCA_120 (0x0A) /* RCA 120 RAM */ + +#define MANUF_IMTRONICS2 (0x1028) /* Imtronics */ +#define PROD_HURRICANE_2800_3 (0x39) /* Hurricane 2800 68030 */ +#define PROD_HURRICANE_2800_4 (0x57) /* Hurricane 2800 68030 */ + +#define MANUF_KUPKE3 (0x1248) /* Kupke */ +#define PROD_GOLEM_3000 (0x01) /* Golem HD 3000 */ + +#define MANUF_INFORMATION (0x157C) /* Information */ +#define PROD_ISDN_ENGINE_I (0x64) /* ISDN Engine I */ + +#define MANUF_VORTEX (0x2017) /* Vortex */ +#define PROD_GOLDEN_GATE_386SX (0x07) /* Golden Gate 80386SX Board */ +#define PROD_GOLDEN_GATE_RAM (0x08) /* Golden Gate RAM */ +#define PROD_GOLDEN_GATE_486 (0x09) /* Golden Gate 80486 Board */ + +#define MANUF_DATAFLYER (0x2062) /* DataFlyer */ +#define PROD_DATAFLYER_4000SXS (0x01) /* DataFlyer 4000SX SCSI Controller */ +#define PROD_DATAFLYER_4000SXR (0x02) /* DataFlyer 4000SX RAM */ + +#define MANUF_READYSOFT (0x2100) /* ReadySoft */ +#define PROD_AMAX (0x01) /* AMax II/IV */ + +#define MANUF_PHASE5 (0x2140) /* Phase5 */ +#define PROD_BLIZZARD_RAM (0x01) /* Blizzard RAM */ +#define PROD_BLIZZARD (0x02) /* Blizzard */ +#define PROD_BLIZZARD_1220_IV (0x06) /* Blizzard 1220-IV Turbo Board */ +#define PROD_FASTLANE_RAM (0x0A) /* FastLane RAM */ +#define PROD_FASTLANE_SCSI (0x0B) /* FastLane/Blizzard 1230-II SCSI/CyberSCSI */ +#define PROD_CYBERSTORM_SCSI (0x0C) /* Blizzard 1220/CyberStorm */ +#define PROD_BLIZZARD_1230_III (0x0D) /* Blizzard 1230-III Turbo Board */ +#define PROD_BLIZZARD_1230_IV (0x11) /* Blizzard 1230-IV/1260 Turbo Board */ +#define PROD_BLIZZARD_2060SCSI (0x18) /* Blizzard 2060 SCSI Controller */ +#define PROD_CYBERSTORM_II (0x19) /* CyberStorm Mk II */ +#define PROD_CYBERVISION (0x22) /* CyberVision64 Graphics Board */ + +#define MANUF_DPS (0x2169) /* DPS */ +#define PROD_DPS_PAR (0x01) /* Personal Animation Recorder */ + +#define MANUF_APOLLO2 (0x2200) /* Apollo */ +#define PROD_A620 (0x00) /* A620 68020 Accelerator */ + +#define MANUF_APOLLO (0x2222) /* Apollo */ +#define PROD_AT_APOLLO (0x22) /* AT-Apollo */ +#define PROD_APOLLO_TURBO (0x23) /* Apollo Turbo Board */ + +#define MANUF_UWE_GERLACH (0x3FF7) /* Uwe Gerlach */ +#define PROD_UG_RAM_ROM (0xd4) /* RAM/ROM */ + +#define MANUF_MACROSYSTEMS2 (0x4754) /* MacroSystems Germany */ +#define PROD_MAESTRO (0x03) /* Maestro */ +#define PROD_VLAB (0x04) /* VLab */ +#define PROD_MAESTRO_PRO (0x05) /* Maestro Pro */ +#define PROD_RETINA_Z2 (0x06) /* Retina Z2 Graphics Board */ +#define PROD_MULTI_EVOLUTION (0x08) /* MultiEvolution */ +#define PROD_TOCCATA (0x0C) /* Toccata Sound Board */ +#define PROD_RETINA_Z3 (0x10) /* Retina Z3 Graphics Board */ +#define PROD_VLAB_MOTION (0x12) /* VLab Motion */ +#define PROD_FALCON_040 (0xFD) /* Falcon '040 Turbo Board */ + +#define MANUF_COMBITEC (0x6766) /* Combitec */ + +#define MANUF_SKI (0x8000) /* SKI Peripherals */ +#define PROD_SKI_SCSI_SERIAL (0x80) /* SCSI / Dual Serial */ + +#define MANUF_CAMERON (0xAA01) /* Cameron */ +#define PROD_CAMERON_SCANNER (0x10) /* Scanner Interface */ + +#define MANUF_REIS_WARE (0xAA11) /* Reis-Ware */ +#define PROD_RW_HANDYSCANNER (0x11) /* Handyscanner */ + + +/* Illegal Manufacturer IDs. These do NOT appear in arch/m68k/amiga/zorro.c! */ + +#define MANUF_HACKER_INC (0x07DB) /* Hacker Inc. */ +#define PROD_HACKER_SCSI (0x01) /* Hacker Inc. SCSI Controller */ + +#define MANUF_RES_MNGT_FORCE (0x07DB) /* Resource Management Force */ +#define PROD_QUICKNET (0x02) /* QuickNet Ethernet */ + +#define MANUF_VECTOR2 (0x07DB) /* Vector */ +#define PROD_CONNECTION_2 (0xE0) /* Vector Connection */ +#define PROD_CONNECTION_3 (0xE1) /* Vector Connection */ +#define PROD_CONNECTION_4 (0xE2) /* Vector Connection */ +#define PROD_CONNECTION_5 (0xE3) /* Vector Connection */ + + +/* + * GVP's identifies most of their product through the 'extended + * product code' (epc). The epc has to be and'ed with the GVP_PRODMASK + * before the identification. + */ + +#define GVP_PRODMASK (0xf8) +#define GVP_SCSICLKMASK (0x01) + +enum GVP_ident { + GVP_GFORCE_040 = 0x20, + GVP_GFORCE_040_SCSI = 0x30, + GVP_A1291_SCSI = 0x40, + GVP_COMBO_R4 = 0x60, + GVP_COMBO_R4_SCSI = 0x70, + GVP_PHONEPAK = 0x78, + GVP_IOEXT = 0x98, + GVP_GFORCE_030 = 0xa0, + GVP_GFORCE_030_SCSI = 0xb0, + GVP_A530 = 0xc0, + GVP_A530_SCSI = 0xd0, + GVP_COMBO_R3 = 0xe0, + GVP_COMBO_R3_SCSI = 0xf0, + GVP_SERIESII = 0xf8, +}; + +enum GVP_flags { + GVP_IO = 0x01, + GVP_ACCEL = 0x02, + GVP_SCSI = 0x04, + GVP_24BITDMA = 0x08, + GVP_25BITDMA = 0x10, + GVP_NOBANK = 0x20, + GVP_14MHZ = 0x40, +}; + + +struct Node { + struct Node *ln_Succ; /* Pointer to next (successor) */ + struct Node *ln_Pred; /* Pointer to previous (predecessor) */ + u_char ln_Type; + char ln_Pri; /* Priority, for sorting */ + char *ln_Name; /* ID string, null terminated */ +}; + +struct ExpansionRom { + /* -First 16 bytes of the expansion ROM */ + u_char er_Type; /* Board type, size and flags */ + u_char er_Product; /* Product number, assigned by manufacturer */ + u_char er_Flags; /* Flags */ + u_char er_Reserved03; /* Must be zero ($ff inverted) */ + u_short er_Manufacturer; /* Unique ID,ASSIGNED BY COMMODORE-AMIGA! */ + u_long er_SerialNumber; /* Available for use by manufacturer */ + u_short er_InitDiagVec; /* Offset to optional "DiagArea" structure */ + u_char er_Reserved0c; + u_char er_Reserved0d; + u_char er_Reserved0e; + u_char er_Reserved0f; +}; + +/* er_Type board type bits */ +#define ERT_TYPEMASK 0xc0 +#define ERT_ZORROII 0xc0 +#define ERT_ZORROIII 0x80 + +/* other bits defined in er_Type */ +#define ERTB_MEMLIST 5 /* Link RAM into free memory list */ +#define ERTF_MEMLIST (1<<5) + +struct ConfigDev { + struct Node cd_Node; + u_char cd_Flags; /* (read/write) */ + u_char cd_Pad; /* reserved */ + struct ExpansionRom cd_Rom; /* copy of board's expansion ROM */ + void *cd_BoardAddr; /* where in memory the board was placed */ + u_long cd_BoardSize; /* size of board in bytes */ + u_short cd_SlotAddr; /* which slot number (PRIVATE) */ + u_short cd_SlotSize; /* number of slots (PRIVATE) */ + void *cd_Driver; /* pointer to node of driver */ + struct ConfigDev *cd_NextCD; /* linked list of drivers to config */ + u_long cd_Unused[4]; /* for whatever the driver wants */ +}; + +#else /* __ASSEMBLY__ */ + +LN_Succ = 0 +LN_Pred = LN_Succ+4 +LN_Type = LN_Pred+4 +LN_Pri = LN_Type+1 +LN_Name = LN_Pri+1 +LN_sizeof = LN_Name+4 + +ER_Type = 0 +ER_Product = ER_Type+1 +ER_Flags = ER_Product+1 +ER_Reserved03 = ER_Flags+1 +ER_Manufacturer = ER_Reserved03+1 +ER_SerialNumber = ER_Manufacturer+2 +ER_InitDiagVec = ER_SerialNumber+4 +ER_Reserved0c = ER_InitDiagVec+2 +ER_Reserved0d = ER_Reserved0c+1 +ER_Reserved0e = ER_Reserved0d+1 +ER_Reserved0f = ER_Reserved0e+1 +ER_sizeof = ER_Reserved0f+1 + +CD_Node = 0 +CD_Flags = CD_Node+LN_sizeof +CD_Pad = CD_Flags+1 +CD_Rom = CD_Pad+1 +CD_BoardAddr = CD_Rom+ER_sizeof +CD_BoardSize = CD_BoardAddr+4 +CD_SlotAddr = CD_BoardSize+4 +CD_SlotSize = CD_SlotAddr+2 +CD_Driver = CD_SlotSize+2 +CD_NextCD = CD_Driver+4 +CD_Unused = CD_NextCD+4 +CD_sizeof = CD_Unused+(4*4) + +#endif /* __ASSEMBLY__ */ + +#ifndef __ASSEMBLY__ + +/* + * Zorro Functions + */ + +extern int zorro_find(int manuf, int prod, int part, int index); +extern struct ConfigDev *zorro_get_board(int key); +extern void zorro_config_board(int key, int part); +extern void zorro_unconfig_board(int key, int part); + + +/* + * Bitmask indicating portions of available Zorro II RAM that are unused + * by the system. Every bit represents a 64K chunk, for a maximum of 8MB + * (128 chunks, physical 0x00200000-0x009fffff). + * + * If you want to use (= allocate) portions of this RAM, you should clear + * the corresponding bits. + */ + +extern u_long zorro_unused_z2ram[4]; + +#define Z2RAM_START (0x00200000) +#define Z2RAM_END (0x00a00000) +#define Z2RAM_SIZE (0x00800000) +#define Z2RAM_CHUNKSIZE (0x00010000) +#define Z2RAM_CHUNKMASK (0x0000ffff) +#define Z2RAM_CHUNKSHIFT (16) + + +/* + * Verbose Board Identification + */ + +#ifdef CONFIG_ZORRO +extern void zorro_identify(void); +extern int zorro_get_list(char *buffer); +#endif CONFIG_ZORRO + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_M68K_ZORRO_H_ */ |