diff options
author | Linus Torvalds | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/asm-m68k |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/asm-m68k')
161 files changed, 16748 insertions, 0 deletions
diff --git a/include/asm-m68k/a.out.h b/include/asm-m68k/a.out.h new file mode 100644 index 000000000000..eda1662773b8 --- /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/adb.h b/include/asm-m68k/adb.h new file mode 100644 index 000000000000..9176b55185bb --- /dev/null +++ b/include/asm-m68k/adb.h @@ -0,0 +1,75 @@ +/* + * Definitions for talking to ADB and CUDA. The CUDA is a microcontroller + * which controls the ADB, system power, RTC, and various other things on + * later Macintoshes + * + * Copyright (C) 1996 Paul Mackerras. + */ + +/* First byte sent to or received from CUDA */ +#define ADB_PACKET 0 +#define CUDA_PACKET 1 +#define ERROR_PACKET 2 +#define TIMER_PACKET 3 +#define POWER_PACKET 4 +#define MACIIC_PACKET 5 + +/* ADB commands (2nd byte) */ +#define ADB_BUSRESET 0 +#define ADB_FLUSH(id) (1 + ((id) << 4)) +#define ADB_WRITEREG(id, reg) (8 + (reg) + ((id) << 4)) +#define ADB_READREG(id, reg) (0xc + (reg) + ((id) << 4)) + +/* ADB default device IDs (upper 4 bits of 2nd byte) */ +#define ADB_DONGLE 1 /* "software execution control" devices */ +#define ADB_KEYBOARD 2 +#define ADB_MOUSE 3 +#define ADB_TABLET 4 +#define ADB_MODEM 5 +#define ADB_MISC 7 /* maybe a monitor */ + +/* CUDA commands (2nd byte) */ +#define CUDA_WARM_START 0 +#define CUDA_AUTOPOLL 1 +#define CUDA_GET_6805_ADDR 2 +#define CUDA_GET_TIME 3 +#define CUDA_GET_PRAM 7 +#define CUDA_SET_6805_ADDR 8 +#define CUDA_SET_TIME 9 +#define CUDA_POWERDOWN 0xa +#define CUDA_POWERUP_TIME 0xb +#define CUDA_SET_PRAM 0xc +#define CUDA_MS_RESET 0xd +#define CUDA_SEND_DFAC 0xe +#define CUDA_RESET_SYSTEM 0x11 +#define CUDA_SET_IPL 0x12 +#define CUDA_SET_AUTO_RATE 0x14 +#define CUDA_GET_AUTO_RATE 0x16 +#define CUDA_SET_DEVICE_LIST 0x19 +#define CUDA_GET_DEVICE_LIST 0x1a +#define CUDA_GET_SET_IIC 0x22 + +#ifdef __KERNEL__ + +struct adb_request { + unsigned char data[16]; + int nbytes; + unsigned char reply[16]; + int reply_len; + unsigned char reply_expected; + unsigned char sent; + unsigned char got_reply; + void (*done)(struct adb_request *); + void *arg; + struct adb_request *next; +}; + +void via_adb_init(void); +int adb_request(struct adb_request *req, + void (*done)(struct adb_request *), int nbytes, ...); +int adb_send_request(struct adb_request *req); +void adb_poll(void); +int adb_register(int default_id, + void (*handler)(unsigned char *, int, struct pt_regs *)); + +#endif /* __KERNEL */ diff --git a/include/asm-m68k/adb_iop.h b/include/asm-m68k/adb_iop.h new file mode 100644 index 000000000000..8a48e56f2d62 --- /dev/null +++ b/include/asm-m68k/adb_iop.h @@ -0,0 +1,44 @@ +/* + * ADB through the IOP + * Written by Joshua M. Thompson + */ + +/* IOP number and channel number for ADB */ + +#define ADB_IOP IOP_NUM_ISM +#define ADB_CHAN 2 + +/* From the A/UX headers...maybe important, maybe not */ + +#define ADB_IOP_LISTEN 0x01 +#define ADB_IOP_TALK 0x02 +#define ADB_IOP_EXISTS 0x04 +#define ADB_IOP_FLUSH 0x08 +#define ADB_IOP_RESET 0x10 +#define ADB_IOP_INT 0x20 +#define ADB_IOP_POLL 0x40 +#define ADB_IOP_UNINT 0x80 + +#define AIF_RESET 0x00 +#define AIF_FLUSH 0x01 +#define AIF_LISTEN 0x08 +#define AIF_TALK 0x0C + +/* Flag bits in struct adb_iopmsg */ + +#define ADB_IOP_EXPLICIT 0x80 /* nonzero if explicit command */ +#define ADB_IOP_AUTOPOLL 0x40 /* auto/SRQ polling enabled */ +#define ADB_IOP_SRQ 0x04 /* SRQ detected */ +#define ADB_IOP_TIMEOUT 0x02 /* nonzero if timeout */ + +#ifndef __ASSEMBLY__ + +struct adb_iopmsg { + __u8 flags; /* ADB flags */ + __u8 count; /* no. of data bytes */ + __u8 cmd; /* ADB command */ + __u8 data[8]; /* ADB data */ + __u8 spare[21]; /* spare */ +}; + +#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h new file mode 100644 index 000000000000..3ae5d8d55ba9 --- /dev/null +++ b/include/asm-m68k/amigahw.h @@ -0,0 +1,354 @@ +/* +** 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 _M68K_AMIGAHW_H +#define _M68K_AMIGAHW_H + +#include <linux/ioport.h> + + /* + * Different Amiga models + */ + +extern unsigned long amiga_model; + +#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 + */ + +extern unsigned long amiga_chipset; + +#define CS_STONEAGE (0) +#define CS_OCS (1) +#define CS_ECS (2) +#define CS_AGA (3) + + + /* + * Miscellaneous + */ + +extern unsigned long amiga_eclock; /* 700 kHz E Peripheral Clock */ +extern unsigned long amiga_masterclock; /* 28 MHz Master Clock */ +extern unsigned long amiga_colorclock; /* 3.5 MHz Color Clock */ +extern unsigned long amiga_chip_size; /* Chip RAM Size (bytes) */ +extern unsigned char amiga_vblank; /* VBLANK Frequency */ +extern unsigned char amiga_psfreq; /* Power Supply Frequency */ + + +#define AMIGAHW_DECLARE(name) unsigned name : 1 +#define AMIGAHW_SET(name) (amiga_hw_present.name = 1) +#define AMIGAHW_PRESENT(name) (amiga_hw_present.name) + +struct amiga_hw_present { + /* 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(PCMCIA); /* PCMCIA Slot */ + AMIGAHW_DECLARE(GG2_ISA); /* GG2 Zorro2ISA Bridge */ + AMIGAHW_DECLARE(ZORRO); /* Zorro AutoConfig */ + AMIGAHW_DECLARE(ZORRO3); /* Zorro III */ +}; + +extern struct amiga_hw_present amiga_hw_present; + +struct CUSTOM { + unsigned short bltddat; + unsigned short dmaconr; + unsigned short vposr; + unsigned short vhposr; + unsigned short dskdatr; + unsigned short joy0dat; + unsigned short joy1dat; + unsigned short clxdat; + unsigned short adkconr; + unsigned short pot0dat; + unsigned short pot1dat; + unsigned short potgor; + unsigned short serdatr; + unsigned short dskbytr; + unsigned short intenar; + unsigned short intreqr; + unsigned char *dskptr; + unsigned short dsklen; + unsigned short dskdat; + unsigned short refptr; + unsigned short vposw; + unsigned short vhposw; + unsigned short copcon; + unsigned short serdat; + unsigned short serper; + unsigned short potgo; + unsigned short joytest; + unsigned short strequ; + unsigned short strvbl; + unsigned short strhor; + unsigned short strlong; + unsigned short bltcon0; + unsigned short bltcon1; + unsigned short bltafwm; + unsigned short bltalwm; + unsigned char *bltcpt; + unsigned char *bltbpt; + unsigned char *bltapt; + unsigned char *bltdpt; + unsigned short bltsize; + unsigned char pad2d; + unsigned char bltcon0l; + unsigned short bltsizv; + unsigned short bltsizh; + unsigned short bltcmod; + unsigned short bltbmod; + unsigned short bltamod; + unsigned short bltdmod; + unsigned short spare2[4]; + unsigned short bltcdat; + unsigned short bltbdat; + unsigned short bltadat; + unsigned short spare3[3]; + unsigned short deniseid; + unsigned short dsksync; + unsigned short *cop1lc; + unsigned short *cop2lc; + unsigned short copjmp1; + unsigned short copjmp2; + unsigned short copins; + unsigned short diwstrt; + unsigned short diwstop; + unsigned short ddfstrt; + unsigned short ddfstop; + unsigned short dmacon; + unsigned short clxcon; + unsigned short intena; + unsigned short intreq; + unsigned short adkcon; + struct { + unsigned short *audlc; + unsigned short audlen; + unsigned short audper; + unsigned short audvol; + unsigned short auddat; + unsigned short audspare[2]; + } aud[4]; + unsigned char *bplpt[8]; + unsigned short bplcon0; + unsigned short bplcon1; + unsigned short bplcon2; + unsigned short bplcon3; + unsigned short bpl1mod; + unsigned short bpl2mod; + unsigned short bplcon4; + unsigned short clxcon2; + unsigned short bpldat[8]; + unsigned char *sprpt[8]; + struct { + unsigned short pos; + unsigned short ctl; + unsigned short dataa; + unsigned short datab; + } spr[8]; + unsigned short color[32]; + unsigned short htotal; + unsigned short hsstop; + unsigned short hbstrt; + unsigned short hbstop; + unsigned short vtotal; + unsigned short vsstop; + unsigned short vbstrt; + unsigned short vbstop; + unsigned short sprhstrt; + unsigned short sprhstop; + unsigned short bplhstrt; + unsigned short bplhstop; + unsigned short hhposw; + unsigned short hhposr; + unsigned short beamcon0; + unsigned short hsstrt; + unsigned short vsstrt; + unsigned short hcenter; + unsigned short diwhigh; + unsigned short spare4[11]; + unsigned 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 { + unsigned char pra; char pad0[0xff]; + unsigned char prb; char pad1[0xff]; + unsigned char ddra; char pad2[0xff]; + unsigned char ddrb; char pad3[0xff]; + unsigned char talo; char pad4[0xff]; + unsigned char tahi; char pad5[0xff]; + unsigned char tblo; char pad6[0xff]; + unsigned char tbhi; char pad7[0xff]; + unsigned char todlo; char pad8[0xff]; + unsigned char todmid; char pad9[0xff]; + unsigned char todhi; char pada[0x1ff]; + unsigned char sdr; char padb[0xff]; + unsigned char icr; char padc[0xff]; + unsigned char cra; char padd[0xff]; + unsigned char crb; char pade[0xff]; +}; + +#define zTwoBase (0x80000000) +#define ZTWO_PADDR(x) (((unsigned long)(x))-zTwoBase) +#define ZTWO_VADDR(x) (((unsigned long)(x))+zTwoBase) + +#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) + +void amiga_chip_init (void); +void *amiga_chip_alloc(unsigned long size, const char *name); +void *amiga_chip_alloc_res(unsigned long size, struct resource *res); +void amiga_chip_free(void *ptr); +unsigned long amiga_chip_avail( void ); /*MILAN*/ +extern volatile unsigned short amiga_audio_min_period; + +static inline void amifb_video_off(void) +{ + if (amiga_chipset == CS_ECS || amiga_chipset == CS_AGA) { + /* program Denise/Lisa for a higher maximum play rate */ + custom.htotal = 113; /* 31 kHz */ + custom.vtotal = 223; /* 70 Hz */ + custom.beamcon0 = 0x4390; /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */ + /* suspend the monitor */ + custom.hsstrt = custom.hsstop = 116; + custom.vsstrt = custom.vsstop = 226; + amiga_audio_min_period = 57; + } +} + +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 ((*(volatile 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 ((*(volatile struct tod2000 *)(zTwoBase+0xDC0000))) + +#endif /* _M68K_AMIGAHW_H */ diff --git a/include/asm-m68k/amigaints.h b/include/asm-m68k/amigaints.h new file mode 100644 index 000000000000..2aff4cfbf7b3 --- /dev/null +++ b/include/asm-m68k/amigaints.h @@ -0,0 +1,133 @@ +/* +** 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 AUTO_IRQS (8) +#define AMI_STD_IRQS (14) +#define CIA_IRQS (5) +#define AMI_IRQS (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */ + +/* vertical blanking interrupt */ +#define IRQ_AMIGA_VERTB 0 + +/* copper interrupt */ +#define IRQ_AMIGA_COPPER 1 + +/* Audio interrupts */ +#define IRQ_AMIGA_AUD0 2 +#define IRQ_AMIGA_AUD1 3 +#define IRQ_AMIGA_AUD2 4 +#define IRQ_AMIGA_AUD3 5 + +/* Blitter done interrupt */ +#define IRQ_AMIGA_BLIT 6 + +/* floppy disk interrupts */ +#define IRQ_AMIGA_DSKSYN 7 +#define IRQ_AMIGA_DSKBLK 8 + +/* builtin serial port interrupts */ +#define IRQ_AMIGA_RBF 9 +#define IRQ_AMIGA_TBE 10 + +/* software interrupts */ +#define IRQ_AMIGA_SOFT 11 + +/* interrupts from external hardware */ +#define IRQ_AMIGA_PORTS 12 +#define IRQ_AMIGA_EXTER 13 + +/* CIA interrupt sources */ +#define IRQ_AMIGA_CIAA 14 +#define IRQ_AMIGA_CIAA_TA 14 +#define IRQ_AMIGA_CIAA_TB 15 +#define IRQ_AMIGA_CIAA_ALRM 16 +#define IRQ_AMIGA_CIAA_SP 17 +#define IRQ_AMIGA_CIAA_FLG 18 +#define IRQ_AMIGA_CIAB 19 +#define IRQ_AMIGA_CIAB_TA 19 +#define IRQ_AMIGA_CIAB_TB 20 +#define IRQ_AMIGA_CIAB_ALRM 21 +#define IRQ_AMIGA_CIAB_SP 22 +#define IRQ_AMIGA_CIAB_FLG 23 + +/* auto-vector interrupts */ +#define IRQ_AMIGA_AUTO 24 +#define IRQ_AMIGA_AUTO_0 24 /* This is just a dummy */ +#define IRQ_AMIGA_AUTO_1 25 +#define IRQ_AMIGA_AUTO_2 26 +#define IRQ_AMIGA_AUTO_3 27 +#define IRQ_AMIGA_AUTO_4 28 +#define IRQ_AMIGA_AUTO_5 29 +#define IRQ_AMIGA_AUTO_6 30 +#define IRQ_AMIGA_AUTO_7 31 + +#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 */ + +extern void amiga_do_irq(int irq, struct pt_regs *fp); +extern void amiga_do_irq_list(int irq, struct pt_regs *fp); + +extern unsigned short amiga_intena_vals[]; + +/* 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/amigayle.h b/include/asm-m68k/amigayle.h new file mode 100644 index 000000000000..bb5a6aa329f3 --- /dev/null +++ b/include/asm-m68k/amigayle.h @@ -0,0 +1,107 @@ +/* +** asm-m68k/amigayle.h -- This header defines the registers of the gayle chip +** found on the Amiga 1200 +** This information was found by disassembling card.resource, +** so the definitions may not be 100% correct +** anyone has an official doc ? +** +** Copyright 1997 by Alain Malek +** +** 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: 11/28/97 by Alain Malek +*/ + +#ifndef _M68K_AMIGAYLE_H_ +#define _M68K_AMIGAYLE_H_ + +#include <linux/types.h> +#include <asm/amigahw.h> + +/* memory layout */ + +#define GAYLE_RAM (0x600000+zTwoBase) +#define GAYLE_RAMSIZE (0x400000) +#define GAYLE_ATTRIBUTE (0xa00000+zTwoBase) +#define GAYLE_ATTRIBUTESIZE (0x020000) +#define GAYLE_IO (0xa20000+zTwoBase) /* 16bit and even 8bit registers */ +#define GAYLE_IOSIZE (0x010000) +#define GAYLE_IO_8BITODD (0xa30000+zTwoBase) /* odd 8bit registers */ + +/* offset for accessing odd IO registers */ +#define GAYLE_ODD (GAYLE_IO_8BITODD-GAYLE_IO-1) + +/* GAYLE registers */ + +struct GAYLE { + u_char cardstatus; + u_char pad0[0x1000-1]; + + u_char intreq; + u_char pad1[0x1000-1]; + + u_char inten; + u_char pad2[0x1000-1]; + + u_char config; + u_char pad3[0x1000-1]; +}; + +#define GAYLE_ADDRESS (0xda8000) /* gayle main registers base address */ + +#define GAYLE_RESET (0xa40000) /* write 0x00 to start reset, + read 1 byte to stop reset */ + +#define gayle (*(volatile struct GAYLE *)(zTwoBase+GAYLE_ADDRESS)) +#define gayle_reset (*(volatile u_char *)(zTwoBase+GAYLE_RESET)) + +#define gayle_attribute ((volatile u_char *)(GAYLE_ATTRIBUTE)) + +#if 0 +#define gayle_inb(a) readb( GAYLE_IO+(a)+(((a)&1)*GAYLE_ODD) ) +#define gayle_outb(v,a) writeb( v, GAYLE_IO+(a)+(((a)&1)*GAYLE_ODD) ) + +#define gayle_inw(a) readw( GAYLE_IO+(a) ) +#define gayle_outw(v,a) writew( v, GAYLE_IO+(a) ) +#endif + +/* GAYLE_CARDSTATUS bit def */ + +#define GAYLE_CS_CCDET 0x40 /* credit card detect */ +#define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */ +#define GAYLE_CS_SC 0x20 /* credit card status change */ +#define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */ +#define GAYLE_CS_DA 0x10 /* digital audio */ +#define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */ +#define GAYLE_CS_BSY 0x04 /* credit card busy */ +#define GAYLE_CS_IRQ 0x04 /* interrupt request */ + +/* GAYLE_IRQ bit def */ + +#define GAYLE_IRQ_IDE 0x80 +#define GAYLE_IRQ_CCDET 0x40 +#define GAYLE_IRQ_BVD1 0x20 +#define GAYLE_IRQ_SC 0x20 +#define GAYLE_IRQ_BVD2 0x10 +#define GAYLE_IRQ_DA 0x10 +#define GAYLE_IRQ_WR 0x08 +#define GAYLE_IRQ_BSY 0x04 +#define GAYLE_IRQ_IRQ 0x04 +#define GAYLE_IRQ_IDEACK1 0x02 +#define GAYLE_IRQ_IDEACK0 0x01 + +/* GAYLE_CONFIG bit def + (bit 0-1 for program voltage, bit 2-3 for access speed */ + +#define GAYLE_CFG_0V 0x00 +#define GAYLE_CFG_5V 0x01 +#define GAYLE_CFG_12V 0x02 + +#define GAYLE_CFG_100NS 0x08 +#define GAYLE_CFG_150NS 0x04 +#define GAYLE_CFG_250NS 0x00 +#define GAYLE_CFG_720NS 0x0c + +#endif /* asm-m68k/amigayle.h */ diff --git a/include/asm-m68k/amipcmcia.h b/include/asm-m68k/amipcmcia.h new file mode 100644 index 000000000000..6f1ec1887d82 --- /dev/null +++ b/include/asm-m68k/amipcmcia.h @@ -0,0 +1,110 @@ +/* +** asm-m68k/pcmcia.h -- Amiga Linux PCMCIA Definitions +** +** Copyright 1997 by Alain Malek +** +** 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: 12/10/97 by Alain Malek +*/ + +#ifndef __AMIGA_PCMCIA_H__ +#define __AMIGA_PCMCIA_H__ + +#include <asm/amigayle.h> + +/* prototypes */ + +void pcmcia_reset(void); +int pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len); +void pcmcia_program_voltage(int voltage); +void pcmcia_access_speed(int speed); +void pcmcia_write_enable(void); +void pcmcia_write_disable(void); + +static inline u_char pcmcia_read_status(void) +{ + return (gayle.cardstatus & 0x7c); +} + +static inline u_char pcmcia_get_intreq(void) +{ + return (gayle.intreq); +} + +static inline void pcmcia_ack_int(u_char intreq) +{ + gayle.intreq = 0xf8; +} + +static inline void pcmcia_enable_irq(void) +{ + gayle.inten |= GAYLE_IRQ_IRQ; +} + +static inline void pcmcia_disable_irq(void) +{ + gayle.inten &= ~GAYLE_IRQ_IRQ; +} + +#define PCMCIA_INSERTED (gayle.cardstatus & GAYLE_CS_CCDET) + +/* valid voltages for pcmcia_ProgramVoltage */ + +#define PCMCIA_0V 0 +#define PCMCIA_5V 5 +#define PCMCIA_12V 12 + +/* valid speeds for pcmcia_AccessSpeed */ + +#define PCMCIA_SPEED_100NS 100 +#define PCMCIA_SPEED_150NS 150 +#define PCMCIA_SPEED_250NS 250 +#define PCMCIA_SPEED_720NS 720 + +/* PCMCIA Tuple codes */ + +#define CISTPL_NULL 0x00 +#define CISTPL_DEVICE 0x01 +#define CISTPL_LONGLINK_CB 0x02 +#define CISTPL_CONFIG_CB 0x04 +#define CISTPL_CFTABLE_ENTRY_CB 0x05 +#define CISTPL_LONGLINK_MFC 0x06 +#define CISTPL_BAR 0x07 +#define CISTPL_CHECKSUM 0x10 +#define CISTPL_LONGLINK_A 0x11 +#define CISTPL_LONGLINK_C 0x12 +#define CISTPL_LINKTARGET 0x13 +#define CISTPL_NO_LINK 0x14 +#define CISTPL_VERS_1 0x15 +#define CISTPL_ALTSTR 0x16 +#define CISTPL_DEVICE_A 0x17 +#define CISTPL_JEDEC_C 0x18 +#define CISTPL_JEDEC_A 0x19 +#define CISTPL_CONFIG 0x1a +#define CISTPL_CFTABLE_ENTRY 0x1b +#define CISTPL_DEVICE_OC 0x1c +#define CISTPL_DEVICE_OA 0x1d +#define CISTPL_DEVICE_GEO 0x1e +#define CISTPL_DEVICE_GEO_A 0x1f +#define CISTPL_MANFID 0x20 +#define CISTPL_FUNCID 0x21 +#define CISTPL_FUNCE 0x22 +#define CISTPL_SWIL 0x23 +#define CISTPL_END 0xff + +/* FUNCID */ + +#define CISTPL_FUNCID_MULTI 0x00 +#define CISTPL_FUNCID_MEMORY 0x01 +#define CISTPL_FUNCID_SERIAL 0x02 +#define CISTPL_FUNCID_PARALLEL 0x03 +#define CISTPL_FUNCID_FIXED 0x04 +#define CISTPL_FUNCID_VIDEO 0x05 +#define CISTPL_FUNCID_NETWORK 0x06 +#define CISTPL_FUNCID_AIMS 0x07 +#define CISTPL_FUNCID_SCSI 0x08 + +#endif diff --git a/include/asm-m68k/apollodma.h b/include/asm-m68k/apollodma.h new file mode 100644 index 000000000000..6821e3ba32e9 --- /dev/null +++ b/include/asm-m68k/apollodma.h @@ -0,0 +1,248 @@ +/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +#ifndef _ASM_APOLLO_DMA_H +#define _ASM_APOLLO_DMA_H + +#include <asm/apollohw.h> /* need byte IO */ +#include <linux/spinlock.h> /* And spinlocks */ +#include <linux/delay.h> + + +#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val)) +#define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE))) + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + +/* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x10C00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG (IO_DMA1_BASE+0x08) /* command register (w) */ +#define DMA1_STAT_REG (IO_DMA1_BASE+0x08) /* status register (r) */ +#define DMA1_REQ_REG (IO_DMA1_BASE+0x09) /* request register (w) */ +#define DMA1_MASK_REG (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */ +#define DMA1_MODE_REG (IO_DMA1_BASE+0x0B) /* mode register (w) */ +#define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */ +#define DMA1_RESET_REG (IO_DMA1_BASE+0x0D) /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E) /* Clear Mask */ +#define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */ + +#define DMA2_CMD_REG (IO_DMA2_BASE+0x10) /* command register (w) */ +#define DMA2_STAT_REG (IO_DMA2_BASE+0x10) /* status register (r) */ +#define DMA2_REQ_REG (IO_DMA2_BASE+0x12) /* request register (w) */ +#define DMA2_MASK_REG (IO_DMA2_BASE+0x14) /* single-channel mask (w) */ +#define DMA2_MODE_REG (IO_DMA2_BASE+0x16) /* mode register (w) */ +#define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */ +#define DMA2_RESET_REG (IO_DMA2_BASE+0x1A) /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C) /* Clear Mask */ +#define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */ + +#define DMA_ADDR_0 (IO_DMA1_BASE+0x00) /* DMA address registers */ +#define DMA_ADDR_1 (IO_DMA1_BASE+0x02) +#define DMA_ADDR_2 (IO_DMA1_BASE+0x04) +#define DMA_ADDR_3 (IO_DMA1_BASE+0x06) +#define DMA_ADDR_4 (IO_DMA2_BASE+0x00) +#define DMA_ADDR_5 (IO_DMA2_BASE+0x04) +#define DMA_ADDR_6 (IO_DMA2_BASE+0x08) +#define DMA_ADDR_7 (IO_DMA2_BASE+0x0C) + +#define DMA_CNT_0 (IO_DMA1_BASE+0x01) /* DMA count registers */ +#define DMA_CNT_1 (IO_DMA1_BASE+0x03) +#define DMA_CNT_2 (IO_DMA1_BASE+0x05) +#define DMA_CNT_3 (IO_DMA1_BASE+0x07) +#define DMA_CNT_4 (IO_DMA2_BASE+0x02) +#define DMA_CNT_5 (IO_DMA2_BASE+0x06) +#define DMA_CNT_6 (IO_DMA2_BASE+0x0A) +#define DMA_CNT_7 (IO_DMA2_BASE+0x0E) + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +#define DMA_AUTOINIT 0x10 + +#define DMA_8BIT 0 +#define DMA_16BIT 1 +#define DMA_BUSMASTER 2 + +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr, DMA1_MASK_REG); + else + dma_outb(dmanr & 3, DMA2_MASK_REG); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while holding the DMA lock ! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + if (dmanr <= 3) { + dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr<=3)? count : (count<<1); +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +/* These are in arch/m68k/apollo/dma.c: */ +extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type); +extern void dma_unmap_page(unsigned short dma_addr); + +#endif /* _ASM_APOLLO_DMA_H */ diff --git a/include/asm-m68k/apollohw.h b/include/asm-m68k/apollohw.h new file mode 100644 index 000000000000..4304e1c33e17 --- /dev/null +++ b/include/asm-m68k/apollohw.h @@ -0,0 +1,104 @@ +/* apollohw.h : some structures to access apollo HW */ + +#ifndef _ASMm68k_APOLLOHW_H_ +#define _ASMm68k_APOLLOHW_H_ + +/* + apollo models +*/ + +extern u_long apollo_model; + +#define APOLLO_UNKNOWN (0) +#define APOLLO_DN3000 (1) +#define APOLLO_DN3010 (2) +#define APOLLO_DN3500 (3) +#define APOLLO_DN4000 (4) +#define APOLLO_DN4500 (5) + +/* + see scn2681 data sheet for more info. + member names are read_write. +*/ + +#define DECLARE_2681_FIELD(x) unsigned char x; unsigned char dummy##x + +struct SCN2681 { + + DECLARE_2681_FIELD(mra); + DECLARE_2681_FIELD(sra_csra); + DECLARE_2681_FIELD(BRGtest_cra); + DECLARE_2681_FIELD(rhra_thra); + DECLARE_2681_FIELD(ipcr_acr); + DECLARE_2681_FIELD(isr_imr); + DECLARE_2681_FIELD(ctu_ctur); + DECLARE_2681_FIELD(ctl_ctlr); + DECLARE_2681_FIELD(mrb); + DECLARE_2681_FIELD(srb_csrb); + DECLARE_2681_FIELD(tst_crb); + DECLARE_2681_FIELD(rhrb_thrb); + DECLARE_2681_FIELD(reserved); + DECLARE_2681_FIELD(ip_opcr); + DECLARE_2681_FIELD(startCnt_setOutBit); + DECLARE_2681_FIELD(stopCnt_resetOutBit); + +}; + +#if 0 +struct mc146818 { + + unsigned int second1:4, second2:4, alarm_second1:4, alarm_second2:4, + minute1:4, minute2:4, alarm_minute1:4, alarm_minute2:4; + unsigned int hours1:4, hours2:4, alarm_hours1:4, alarm_hours2:4, + day_of_week1:4, day_of_week2:4, day_of_month1:4, day_of_month2:4; + unsigned int month1:4, month2:4, year1:4, year2:4, :16; + +}; +#endif + +struct mc146818 { + unsigned char second, alarm_second; + unsigned char minute, alarm_minute; + unsigned char hours, alarm_hours; + unsigned char day_of_week, day_of_month; + unsigned char month, year; +}; + + +#define IO_BASE 0x80000000 + +extern u_long sio01_physaddr; +extern u_long sio23_physaddr; +extern u_long rtc_physaddr; +extern u_long pica_physaddr; +extern u_long picb_physaddr; +extern u_long cpuctrl_physaddr; +extern u_long timer_physaddr; + +#define SAU7_SIO01_PHYSADDR 0x10400 +#define SAU7_SIO23_PHYSADDR 0x10500 +#define SAU7_RTC_PHYSADDR 0x10900 +#define SAU7_PICA 0x11000 +#define SAU7_PICB 0x11100 +#define SAU7_CPUCTRL 0x10100 +#define SAU7_TIMER 0x010800 + +#define SAU8_SIO01_PHYSADDR 0x8400 +#define SAU8_RTC_PHYSADDR 0x8900 +#define SAU8_PICA 0x9400 +#define SAU8_PICB 0x9500 +#define SAU8_CPUCTRL 0x8100 +#define SAU8_TIMER 0x8800 + +#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + sio01_physaddr))) +#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + sio23_physaddr))) +#define rtc (((volatile struct mc146818 *)(IO_BASE + rtc_physaddr))) +#define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr)) +#define pica (IO_BASE + pica_physaddr) +#define picb (IO_BASE + picb_physaddr) +#define timer (IO_BASE + timer_physaddr) +#define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000)) + +#define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE) + +#endif diff --git a/include/asm-m68k/atafd.h b/include/asm-m68k/atafd.h new file mode 100644 index 000000000000..8456889ee7da --- /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 000000000000..bbf80949fd9f --- /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_SLM.h b/include/asm-m68k/atari_SLM.h new file mode 100644 index 000000000000..42f4fcdd8bc7 --- /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 000000000000..10fea68f191a --- /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 000000000000..93be7da9f2c7 --- /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; + wait_queue_head_t wait; +}; + +#endif diff --git a/include/asm-m68k/atari_stdma.h b/include/asm-m68k/atari_stdma.h new file mode 100644 index 000000000000..64f92880ce43 --- /dev/null +++ b/include/asm-m68k/atari_stdma.h @@ -0,0 +1,23 @@ + +#ifndef _atari_stdma_h +#define _atari_stdma_h + + +#include <asm/irq.h> + + +/***************************** Prototypes *****************************/ + +void stdma_lock(irqreturn_t (*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/atari_stram.h b/include/asm-m68k/atari_stram.h new file mode 100644 index 000000000000..7546d13963be --- /dev/null +++ b/include/asm-m68k/atari_stram.h @@ -0,0 +1,17 @@ +#ifndef _M68K_ATARI_STRAM_H +#define _M68K_ATARI_STRAM_H + +/* + * Functions for Atari ST-RAM management + */ + +/* public interface */ +void *atari_stram_alloc(long size, const char *owner); +void atari_stram_free(void *); + +/* functions called internally by other parts of the kernel */ +void atari_stram_init(void); +void atari_stram_reserve_pages(void *start_mem); +void atari_stram_mem_init_hook (void); + +#endif /*_M68K_ATARI_STRAM_H */ diff --git a/include/asm-m68k/atarihw.h b/include/asm-m68k/atarihw.h new file mode 100644 index 000000000000..f28acd0fd689 --- /dev/null +++ b/include/asm-m68k/atarihw.h @@ -0,0 +1,808 @@ +/* +** linux/atarihw.h -- This header defines some macros and pointers for +** the various Atari custom hardware registers. +** +** Copyright 1994 by Bj”rn 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> +#include <asm/bootinfo.h> +#include <asm/raw_io.h> + +extern u_long atari_mch_cookie; +extern u_long atari_mch_type; +extern u_long atari_switches; +extern int atari_rtc_year_offset; +extern int atari_dont_touch_floppy_select; + +/* convenience macros for testing machine type */ +#define MACH_IS_ST ((atari_mch_cookie >> 16) == ATARI_MCH_ST) +#define MACH_IS_STE ((atari_mch_cookie >> 16) == ATARI_MCH_STE && \ + (atari_mch_cookie & 0xffff) == 0) +#define MACH_IS_MSTE ((atari_mch_cookie >> 16) == ATARI_MCH_STE && \ + (atari_mch_cookie & 0xffff) == 0x10) +#define MACH_IS_TT ((atari_mch_cookie >> 16) == ATARI_MCH_TT) +#define MACH_IS_FALCON ((atari_mch_cookie >> 16) == ATARI_MCH_FALCON) +#define MACH_IS_MEDUSA (atari_mch_type == ATARI_MACH_MEDUSA) +#define MACH_IS_HADES (atari_mch_type == ATARI_MACH_HADES) +#define MACH_IS_AB40 (atari_mch_type == ATARI_MACH_AB40) + +/* values for atari_switches */ +#define ATARI_SWITCH_IKBD 0x01 +#define ATARI_SWITCH_MIDI 0x02 +#define ATARI_SWITCH_SND6 0x04 +#define ATARI_SWITCH_SND7 0x08 +#define ATARI_SWITCH_OVSC_SHIFT 16 +#define ATARI_SWITCH_OVSC_IKBD (ATARI_SWITCH_IKBD << ATARI_SWITCH_OVSC_SHIFT) +#define ATARI_SWITCH_OVSC_MIDI (ATARI_SWITCH_MIDI << ATARI_SWITCH_OVSC_SHIFT) +#define ATARI_SWITCH_OVSC_SND6 (ATARI_SWITCH_SND6 << ATARI_SWITCH_OVSC_SHIFT) +#define ATARI_SWITCH_OVSC_SND7 (ATARI_SWITCH_SND7 << ATARI_SWITCH_OVSC_SHIFT) +#define ATARI_SWITCH_OVSC_MASK 0xffff0000 + +/* + * 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 */ + +#define ATARIHW_DECLARE(name) unsigned name : 1 +#define ATARIHW_SET(name) (atari_hw_present.name = 1) +#define ATARIHW_PRESENT(name) (atari_hw_present.name) + +struct atari_hw_present { + /* 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 */ + ATARIHW_DECLARE(DSP56K); /* DSP56k processor in Falcon */ +}; + +extern struct atari_hw_present atari_hw_present; + + +/* 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" ); + +/* 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). + */ + + +#define atari_readb raw_inb +#define atari_writeb raw_outb + +#define atari_inb_p raw_inb +#define atari_outb_p raw_outb + + + +#include <linux/mm.h> +#include <asm/cacheflush.h> + +static inline void dma_cache_maintenance( unsigned long paddr, + unsigned long len, + int writeflag ) + +{ + if (writeflag) { + if (!MACH_IS_MEDUSA || CPU_IS_060) + cache_push( paddr, len ); + } + else { + if (!MACH_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 falcon_matrix (*(volatile struct MATRIX *)MATRIX_BASE) + +#define CODEC_BASE (0xffff8936) +struct CODEC +{ + u_char tracks; + u_char input_source; +#define CODEC_SOURCE_ADC 1 +#define CODEC_SOURCE_MATRIX 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 falcon_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_MFP_INT_REPLAY 0x01 +#define DMASND_MFP_INT_RECORD 0x02 +#define DMASND_TIMERA_INT_REPLAY 0x04 +#define DMASND_TIMERA_INT_RECORD 0x08 + +#define DMASND_CTRL_OFF 0x00 +#define DMASND_CTRL_ON 0x01 +#define DMASND_CTRL_REPEAT 0x02 +#define DMASND_CTRL_RECORD_ON 0x10 +#define DMASND_CTRL_RECORD_OFF 0x00 +#define DMASND_CTRL_RECORD_REPEAT 0x20 +#define DMASND_CTRL_SELECT_REPLAY 0x00 +#define DMASND_CTRL_SELECT_RECORD 0x80 +#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 000000000000..42952c890593 --- /dev/null +++ b/include/asm-m68k/atariints.h @@ -0,0 +1,215 @@ +/* +** atariints.h -- Atari Linux interrupt handling structs and prototypes +** +** Copyright 1994 by Bj”rn 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 (0) + +/* auto-vector interrupts */ +#define IRQ_AUTO_1 (1) +#define IRQ_AUTO_2 (2) +#define IRQ_AUTO_3 (3) +#define IRQ_AUTO_4 (4) +#define IRQ_AUTO_5 (5) +#define IRQ_AUTO_6 (6) +#define IRQ_AUTO_7 (7) + +/* ST-MFP interrupts */ +#define IRQ_MFP_BUSY (8) +#define IRQ_MFP_DCD (9) +#define IRQ_MFP_CTS (10) +#define IRQ_MFP_GPU (11) +#define IRQ_MFP_TIMD (12) +#define IRQ_MFP_TIMC (13) +#define IRQ_MFP_ACIA (14) +#define IRQ_MFP_FDC (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 (16) +#define IRQ_MFP_SERERR (17) +#define IRQ_MFP_SEREMPT (18) +#define IRQ_MFP_RECERR (19) +#define IRQ_MFP_RECFULL (20) +#define IRQ_MFP_TIMA (21) +#define IRQ_MFP_RI (22) +#define IRQ_MFP_MMD (23) + +/* TT-MFP interrupts */ +#define IRQ_TT_MFP_IO0 (24) +#define IRQ_TT_MFP_IO1 (25) +#define IRQ_TT_MFP_SCC (26) +#define IRQ_TT_MFP_RI (27) +#define IRQ_TT_MFP_TIMD (28) +#define IRQ_TT_MFP_TIMC (29) +#define IRQ_TT_MFP_DRVRDY (30) +#define IRQ_TT_MFP_SCSIDMA (31) +#define IRQ_TT_MFP_TIMB (32) +#define IRQ_TT_MFP_SERERR (33) +#define IRQ_TT_MFP_SEREMPT (34) +#define IRQ_TT_MFP_RECERR (35) +#define IRQ_TT_MFP_RECFULL (36) +#define IRQ_TT_MFP_TIMA (37) +#define IRQ_TT_MFP_RTC (38) +#define IRQ_TT_MFP_SCSI (39) + +/* SCC interrupts */ +#define IRQ_SCCB_TX (40) +#define IRQ_SCCB_STAT (42) +#define IRQ_SCCB_RX (44) +#define IRQ_SCCB_SPCOND (46) +#define IRQ_SCCA_TX (48) +#define IRQ_SCCA_STAT (50) +#define IRQ_SCCA_RX (52) +#define IRQ_SCCA_SPCOND (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 ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + set_mfp_bit( irq, MFP_MASK ); +} + +static inline void atari_disable_irq( unsigned irq ) + +{ + 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" + */ + +static inline void atari_turnon_irq( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + set_mfp_bit( irq, MFP_ENABLE ); +} + +static inline void atari_turnoff_irq( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_ENABLE ); + clear_mfp_bit( irq, MFP_PENDING ); +} + +static inline void atari_clear_pending_irq( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_PENDING ); +} + +static inline int atari_irq_pending( unsigned irq ) + +{ + 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 000000000000..18926058fde7 --- /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 000000000000..38f3043e7fe1 --- /dev/null +++ b/include/asm-m68k/atomic.h @@ -0,0 +1,148 @@ +#ifndef __ARCH_M68K_ATOMIC__ +#define __ARCH_M68K_ATOMIC__ + +#include <linux/config.h> + +#include <asm/system.h> /* local_irq_XXX() */ + +/* + * 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 struct { int counter; } atomic_t; +#define ATOMIC_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v, i) (((v)->counter) = i) + +static inline void atomic_add(int i, atomic_t *v) +{ + __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i)); +} + +static inline void atomic_sub(int 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; +} + +static inline int atomic_inc_and_test(atomic_t *v) +{ + char c; + __asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v)); + return c != 0; +} + +#ifdef CONFIG_RMW_INSNS +static inline int atomic_add_return(int i, atomic_t *v) +{ + int t, tmp; + + __asm__ __volatile__( + "1: movel %2,%1\n" + " addl %3,%1\n" + " casl %2,%1,%0\n" + " jne 1b" + : "+m" (*v), "=&d" (t), "=&d" (tmp) + : "g" (i), "2" (atomic_read(v))); + return t; +} + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + int t, tmp; + + __asm__ __volatile__( + "1: movel %2,%1\n" + " subl %3,%1\n" + " casl %2,%1,%0\n" + " jne 1b" + : "+m" (*v), "=&d" (t), "=&d" (tmp) + : "g" (i), "2" (atomic_read(v))); + return t; +} +#else /* !CONFIG_RMW_INSNS */ +static inline int atomic_add_return(int i, atomic_t * v) +{ + unsigned long flags; + int t; + + local_irq_save(flags); + t = atomic_read(v); + t += i; + atomic_set(v, t); + local_irq_restore(flags); + + return t; +} + +static inline int atomic_sub_return(int i, atomic_t * v) +{ + unsigned long flags; + int t; + + local_irq_save(flags); + t = atomic_read(v); + t -= i; + atomic_set(v, t); + local_irq_restore(flags); + + return t; +} +#endif /* !CONFIG_RMW_INSNS */ + +#define atomic_dec_return(v) atomic_sub_return(1, (v)) +#define atomic_inc_return(v) atomic_add_return(1, (v)) + +static inline int atomic_sub_and_test(int i, atomic_t *v) +{ + char c; + __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i)); + return c != 0; +} + +static inline int atomic_add_negative(int i, atomic_t *v) +{ + char c; + __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i)); + return c != 0; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *v) +{ + __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask))); +} + +static inline void atomic_set_mask(unsigned long mask, unsigned long *v) +{ + __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask)); +} + +/* Atomic operations are already serializing */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#endif /* __ARCH_M68K_ATOMIC __ */ diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h new file mode 100644 index 000000000000..b1bcf7c66516 --- /dev/null +++ b/include/asm-m68k/bitops.h @@ -0,0 +1,436 @@ +#ifndef _M68K_BITOPS_H +#define _M68K_BITOPS_H +/* + * Copyright 1992, Linus Torvalds. + * + * 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. + */ + +#include <linux/compiler.h> + +/* + * Require 68020 or better. + * + * They use the standard big-endian m680x0 bit ordering. + */ + +#define test_and_set_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_test_and_set_bit(nr, vaddr) : \ + __generic_test_and_set_bit(nr, vaddr)) + +#define __test_and_set_bit(nr,vaddr) test_and_set_bit(nr,vaddr) + +static inline int __constant_test_and_set_bit(int nr, unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + char retval; + + __asm__ __volatile__ ("bset %2,%1; sne %0" + : "=d" (retval), "+m" (*p) + : "di" (nr & 7)); + + return retval; +} + +static inline int __generic_test_and_set_bit(int nr, unsigned long *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); + + return retval; +} + +#define set_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_set_bit(nr, vaddr) : \ + __generic_set_bit(nr, vaddr)) + +#define __set_bit(nr,vaddr) set_bit(nr,vaddr) + +static inline void __constant_set_bit(int nr, volatile unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + __asm__ __volatile__ ("bset %1,%0" + : "+m" (*p) : "di" (nr & 7)); +} + +static inline void __generic_set_bit(int nr, volatile unsigned long *vaddr) +{ + __asm__ __volatile__ ("bfset %1{%0:#1}" + : : "d" (nr^31), "o" (*vaddr) : "memory"); +} + +#define test_and_clear_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_test_and_clear_bit(nr, vaddr) : \ + __generic_test_and_clear_bit(nr, vaddr)) + +#define __test_and_clear_bit(nr,vaddr) test_and_clear_bit(nr,vaddr) + +static inline int __constant_test_and_clear_bit(int nr, unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + char retval; + + __asm__ __volatile__ ("bclr %2,%1; sne %0" + : "=d" (retval), "+m" (*p) + : "di" (nr & 7)); + + return retval; +} + +static inline int __generic_test_and_clear_bit(int nr, unsigned long *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); + + return retval; +} + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +#define clear_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_clear_bit(nr, vaddr) : \ + __generic_clear_bit(nr, vaddr)) +#define __clear_bit(nr,vaddr) clear_bit(nr,vaddr) + +static inline void __constant_clear_bit(int nr, volatile unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + __asm__ __volatile__ ("bclr %1,%0" + : "+m" (*p) : "di" (nr & 7)); +} + +static inline void __generic_clear_bit(int nr, volatile unsigned long *vaddr) +{ + __asm__ __volatile__ ("bfclr %1{%0:#1}" + : : "d" (nr^31), "o" (*vaddr) : "memory"); +} + +#define test_and_change_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_test_and_change_bit(nr, vaddr) : \ + __generic_test_and_change_bit(nr, vaddr)) + +#define __test_and_change_bit(nr,vaddr) test_and_change_bit(nr,vaddr) +#define __change_bit(nr,vaddr) change_bit(nr,vaddr) + +static inline int __constant_test_and_change_bit(int nr, unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + char retval; + + __asm__ __volatile__ ("bchg %2,%1; sne %0" + : "=d" (retval), "+m" (*p) + : "di" (nr & 7)); + + return retval; +} + +static inline int __generic_test_and_change_bit(int nr, unsigned long *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfchg %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); + + return retval; +} + +#define change_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_change_bit(nr, vaddr) : \ + __generic_change_bit(nr, vaddr)) + +static inline void __constant_change_bit(int nr, unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + __asm__ __volatile__ ("bchg %1,%0" + : "+m" (*p) : "di" (nr & 7)); +} + +static inline void __generic_change_bit(int nr, unsigned long *vaddr) +{ + __asm__ __volatile__ ("bfchg %1{%0:#1}" + : : "d" (nr^31), "o" (*vaddr) : "memory"); +} + +static inline int test_bit(int nr, const unsigned long *vaddr) +{ + return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0; +} + +static inline int find_first_zero_bit(const unsigned long *vaddr, + unsigned size) +{ + const unsigned long *p = vaddr; + int res = 32; + unsigned long num; + + if (!size) + return 0; + + size = (size + 31) >> 5; + while (!(num = ~*p++)) { + if (!--size) + goto out; + } + + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + res ^= 31; +out: + return ((long)p - (long)vaddr - 4) * 8 + res; +} + +static inline int find_next_zero_bit(const unsigned long *vaddr, int size, + int offset) +{ + const unsigned long *p = vaddr + (offset >> 5); + int bit = offset & 31UL, res; + + if (offset >= size) + return size; + + if (bit) { + unsigned long num = ~*p++ & (~0UL << bit); + offset -= bit; + + /* Look for zero in first longword */ + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + if (res < 32) + return offset + (res ^ 31); + offset += 32; + } + /* No zero yet, search remaining full bytes for a zero */ + res = find_first_zero_bit(p, size - ((long)p - (long)vaddr) * 8); + return offset + res; +} + +static inline int find_first_bit(const unsigned long *vaddr, unsigned size) +{ + const unsigned long *p = vaddr; + int res = 32; + unsigned long num; + + if (!size) + return 0; + + size = (size + 31) >> 5; + while (!(num = *p++)) { + if (!--size) + goto out; + } + + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + res ^= 31; +out: + return ((long)p - (long)vaddr - 4) * 8 + res; +} + +static inline int find_next_bit(const unsigned long *vaddr, int size, + int offset) +{ + const unsigned long *p = vaddr + (offset >> 5); + int bit = offset & 31UL, res; + + if (offset >= size) + return size; + + if (bit) { + unsigned long num = *p++ & (~0UL << bit); + offset -= bit; + + /* Look for one in first longword */ + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + if (res < 32) + return offset + (res ^ 31); + offset += 32; + } + /* No one yet, search remaining full bytes for a one */ + res = find_first_bit(p, size - ((long)p - (long)vaddr) * 8); + return offset + res; +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +static inline unsigned long ffz(unsigned long word) +{ + int res; + + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (~word & -~word)); + return res ^ 31; +} + +#ifdef __KERNEL__ + +/* + * ffs: find first bit set. This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ + +static inline int ffs(int x) +{ + int cnt; + + asm ("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x)); + + return 32 - cnt; +} +#define __ffs(x) (ffs(x) - 1) + +/* + * fls: find last bit set. + */ + +static inline int fls(int x) +{ + int cnt; + + asm ("bfffo %1{#0,#0},%0" : "=d" (cnt) : "dm" (x)); + + return 32 - cnt; +} + +/* + * Every architecture must define this function. It's the fastest + * way of searching a 140-bit bitmap where the first 100 bits are + * unlikely to be set. It's guaranteed that at least one of the 140 + * bits is cleared. + */ +static inline int sched_find_first_bit(const unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (b[3]) + return __ffs(b[3]) + 96; + return __ffs(b[4]) + 128; +} + + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +/* Bitmap functions for the minix filesystem */ + +static 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); +} + +#define minix_test_and_set_bit(nr, addr) test_and_set_bit((nr) ^ 16, (unsigned long *)(addr)) +#define minix_set_bit(nr,addr) set_bit((nr) ^ 16, (unsigned long *)(addr)) +#define minix_test_and_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 16, (unsigned long *)(addr)) + +static inline int minix_test_bit(int nr, const void *vaddr) +{ + const unsigned short *p = vaddr; + return (p[nr >> 4] & (1U << (nr & 15))) != 0; +} + +/* Bitmap functions for the ext2 filesystem. */ + +#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 24, (unsigned long *)(addr)) +#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 24, (unsigned long *)(addr)) +#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr)) +#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr)) + +static inline int ext2_test_bit(int nr, const void *vaddr) +{ + const unsigned char *p = vaddr; + return (p[nr >> 3] & (1U << (nr & 7))) != 0; +} + +static 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; +} + +static 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; +} + +#endif /* __KERNEL__ */ + +#endif /* _M68K_BITOPS_H */ diff --git a/include/asm-m68k/blinken.h b/include/asm-m68k/blinken.h new file mode 100644 index 000000000000..1a749cf7b06d --- /dev/null +++ b/include/asm-m68k/blinken.h @@ -0,0 +1,32 @@ +/* +** asm/blinken.h -- m68k blinkenlights support (currently hp300 only) +** +** (c) 1998 Phil Blundell <philb@gnu.org> +** +** 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_BLINKEN_H +#define _M68K_BLINKEN_H + +#include <asm/setup.h> +#include <asm/io.h> + +#define HP300_LEDS 0xf001ffff + +extern unsigned char ledstate; + +static __inline__ void blinken_leds(int on, int off) +{ + if (MACH_IS_HP300) + { + ledstate |= on; + ledstate &= ~off; + out_8(HP300_LEDS, ~ledstate); + } +} + +#endif diff --git a/include/asm-m68k/bootinfo.h b/include/asm-m68k/bootinfo.h new file mode 100644 index 000000000000..fb8a06b9ab6a --- /dev/null +++ b/include/asm-m68k/bootinfo.h @@ -0,0 +1,378 @@ +/* +** asm/bootinfo.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. +** 5/10/96 Geert Uytterhoeven: +** Redesign of the boot information structure; renamed to bootinfo.h again +** 27/11/96 Geert Uytterhoeven: +** Backwards compatibility with bootinfo interface version 1.0 +*/ + +#ifndef _M68K_BOOTINFO_H +#define _M68K_BOOTINFO_H + + + /* + * Bootinfo definitions + * + * This is an easily parsable and extendable structure containing all + * information to be passed from the bootstrap to the kernel. + * + * This way I hope to keep all future changes back/forewards compatible. + * Thus, keep your fingers crossed... + * + * This structure is copied right after the kernel bss by the bootstrap + * routine. + */ + +#ifndef __ASSEMBLY__ + +struct bi_record { + unsigned short tag; /* tag ID */ + unsigned short size; /* size of record (in bytes) */ + unsigned long data[0]; /* data */ +}; + +#endif /* __ASSEMBLY__ */ + + + /* + * Tag Definitions + * + * Machine independent tags start counting from 0x0000 + * Machine dependent tags start counting from 0x8000 + */ + +#define BI_LAST 0x0000 /* last record (sentinel) */ +#define BI_MACHTYPE 0x0001 /* machine type (u_long) */ +#define BI_CPUTYPE 0x0002 /* cpu type (u_long) */ +#define BI_FPUTYPE 0x0003 /* fpu type (u_long) */ +#define BI_MMUTYPE 0x0004 /* mmu type (u_long) */ +#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */ + /* (struct mem_info) */ +#define BI_RAMDISK 0x0006 /* ramdisk address and size */ + /* (struct mem_info) */ +#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */ + /* (string) */ + + /* + * Amiga-specific tags + */ + +#define BI_AMIGA_MODEL 0x8000 /* model (u_long) */ +#define BI_AMIGA_AUTOCON 0x8001 /* AutoConfig device */ + /* (struct ConfigDev) */ +#define BI_AMIGA_CHIP_SIZE 0x8002 /* size of Chip RAM (u_long) */ +#define BI_AMIGA_VBLANK 0x8003 /* VBLANK frequency (u_char) */ +#define BI_AMIGA_PSFREQ 0x8004 /* power supply frequency (u_char) */ +#define BI_AMIGA_ECLOCK 0x8005 /* EClock frequency (u_long) */ +#define BI_AMIGA_CHIPSET 0x8006 /* native chipset present (u_long) */ +#define BI_AMIGA_SERPER 0x8007 /* serial port period (u_short) */ + + /* + * Atari-specific tags + */ + +#define BI_ATARI_MCH_COOKIE 0x8000 /* _MCH cookie from TOS (u_long) */ +#define BI_ATARI_MCH_TYPE 0x8001 /* special machine type (u_long) */ + /* (values are ATARI_MACH_* defines */ + +/* 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 + +/* mch_type values */ +#define ATARI_MACH_NORMAL 0 /* no special machine type */ +#define ATARI_MACH_MEDUSA 1 /* Medusa 040 */ +#define ATARI_MACH_HADES 2 /* Hades 040 or 060 */ +#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */ + + /* + * VME-specific tags + */ + +#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */ +#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */ + +/* BI_VME_TYPE codes */ +#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */ +#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */ +#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */ +#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */ +#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */ +#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */ +#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */ +#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */ +#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */ + +/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on + * Motorola VME boards. Contains board number, Bug version, board + * configuration options, etc. See include/asm/mvme16xhw.h for details. + */ + + + /* + * Macintosh-specific tags (all u_long) + */ + +#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */ +#define BI_MAC_VADDR 0x8001 /* Mac video base address */ +#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */ +#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */ +#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */ +#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */ +#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */ +#define BI_MAC_BTIME 0x8007 /* Mac boot time */ +#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */ +#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */ +#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */ +#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */ + + /* + * Macintosh hardware profile data - unused, see macintosh.h for + * resonable type values + */ + +#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */ +#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */ +#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */ +#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */ +#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */ +#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */ +#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */ +#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */ +#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */ +#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */ +#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */ +#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */ +#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */ +#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */ +#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */ +#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */ +#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */ +#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */ + + /* + * Mac: compatibility with old booter data format (temporarily) + * Fields unused with the new bootinfo can be deleted now; instead of + * adding new fields the struct might be splitted into a hardware address + * part and a hardware type part + */ + +#ifndef __ASSEMBLY__ + +struct mac_booter_data +{ + unsigned long videoaddr; + unsigned long videorow; + unsigned long videodepth; + unsigned long dimensions; + unsigned long args; + unsigned long boottime; + unsigned long gmtbias; + unsigned long bootver; + unsigned long videological; + unsigned long sccbase; + unsigned long id; + unsigned long memsize; + unsigned long serialmf; + unsigned long serialhsk; + unsigned long serialgpi; + unsigned long printmf; + unsigned long printhsk; + unsigned long printgpi; + unsigned long cpuid; + unsigned long rombase; + unsigned long adbdelay; + unsigned long timedbra; +}; + +extern struct mac_booter_data + mac_bi_data; + +#endif + + /* + * Apollo-specific tags + */ + +#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */ + + /* + * HP300-specific tags + */ + +#define BI_HP300_MODEL 0x8000 /* model (u_long) */ +#define BI_HP300_UART_SCODE 0x8001 /* UART select code (u_long) */ +#define BI_HP300_UART_ADDR 0x8002 /* phys. addr of UART (u_long) */ + + /* + * 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( 2, 0 ) +#define ATARI_BOOTI_VERSION MK_BI_VERSION( 2, 1 ) +#define MAC_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define MVME147_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define MVME16x_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define Q40_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define HP300_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) + +#ifdef BOOTINFO_COMPAT_1_0 + + /* + * Backwards compatibility with bootinfo interface version 1.0 + */ + +#define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) +#define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) +#define COMPAT_MAC_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) + +#include <linux/zorro.h> + +#define COMPAT_NUM_AUTO 16 + +struct compat_bi_Amiga { + int model; + int num_autocon; + struct ConfigDev autocon[COMPAT_NUM_AUTO]; + unsigned long chip_size; + unsigned char vblank; + unsigned char psfreq; + unsigned long eclock; + unsigned long chipset; + unsigned long hw_present; +}; + +struct compat_bi_Atari { + unsigned long hw_present; + unsigned long mch_cookie; +}; + +#ifndef __ASSEMBLY__ + +struct compat_bi_Macintosh +{ + unsigned long videoaddr; + unsigned long videorow; + unsigned long videodepth; + unsigned long dimensions; + unsigned long args; + unsigned long boottime; + unsigned long gmtbias; + unsigned long bootver; + unsigned long videological; + unsigned long sccbase; + unsigned long id; + unsigned long memsize; + unsigned long serialmf; + unsigned long serialhsk; + unsigned long serialgpi; + unsigned long printmf; + unsigned long printhsk; + unsigned long printgpi; + unsigned long cpuid; + unsigned long rombase; + unsigned long adbdelay; + unsigned long timedbra; +}; + +#endif + +struct compat_mem_info { + unsigned long addr; + unsigned long size; +}; + +#define COMPAT_NUM_MEMINFO 4 + +#define COMPAT_CPUB_68020 0 +#define COMPAT_CPUB_68030 1 +#define COMPAT_CPUB_68040 2 +#define COMPAT_CPUB_68060 3 +#define COMPAT_FPUB_68881 5 +#define COMPAT_FPUB_68882 6 +#define COMPAT_FPUB_68040 7 +#define COMPAT_FPUB_68060 8 + +#define COMPAT_CPU_68020 (1<<COMPAT_CPUB_68020) +#define COMPAT_CPU_68030 (1<<COMPAT_CPUB_68030) +#define COMPAT_CPU_68040 (1<<COMPAT_CPUB_68040) +#define COMPAT_CPU_68060 (1<<COMPAT_CPUB_68060) +#define COMPAT_CPU_MASK (31) +#define COMPAT_FPU_68881 (1<<COMPAT_FPUB_68881) +#define COMPAT_FPU_68882 (1<<COMPAT_FPUB_68882) +#define COMPAT_FPU_68040 (1<<COMPAT_FPUB_68040) +#define COMPAT_FPU_68060 (1<<COMPAT_FPUB_68060) +#define COMPAT_FPU_MASK (0xfe0) + +#define COMPAT_CL_SIZE (256) + +struct compat_bootinfo { + unsigned long machtype; + unsigned long cputype; + struct compat_mem_info memory[COMPAT_NUM_MEMINFO]; + int num_memory; + unsigned long ramdisk_size; + unsigned long ramdisk_addr; + char command_line[COMPAT_CL_SIZE]; + union { + struct compat_bi_Amiga bi_ami; + struct compat_bi_Atari bi_ata; + struct compat_bi_Macintosh bi_mac; + } bi_un; +}; + +#define bi_amiga bi_un.bi_ami +#define bi_atari bi_un.bi_ata +#define bi_mac bi_un.bi_mac + +#endif /* BOOTINFO_COMPAT_1_0 */ + + +#endif /* _M68K_BOOTINFO_H */ diff --git a/include/asm-m68k/bug.h b/include/asm-m68k/bug.h new file mode 100644 index 000000000000..3e1d2266fa69 --- /dev/null +++ b/include/asm-m68k/bug.h @@ -0,0 +1,27 @@ +#ifndef _M68K_BUG_H +#define _M68K_BUG_H + +#include <linux/config.h> + +#ifdef CONFIG_DEBUG_BUGVERBOSE +#ifndef CONFIG_SUN3 +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + asm volatile("illegal"); \ +} while (0) +#else +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + panic("BUG!"); \ +} while (0) +#endif +#else +#define BUG() do { \ + asm volatile("illegal"); \ +} while (0) +#endif + +#define HAVE_ARCH_BUG +#include <asm-generic/bug.h> + +#endif diff --git a/include/asm-m68k/bugs.h b/include/asm-m68k/bugs.h new file mode 100644 index 000000000000..d01935592410 --- /dev/null +++ b/include/asm-m68k/bugs.h @@ -0,0 +1,14 @@ +/* + * 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); + */ + +extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */ diff --git a/include/asm-m68k/bvme6000hw.h b/include/asm-m68k/bvme6000hw.h new file mode 100644 index 000000000000..28a859b03959 --- /dev/null +++ b/include/asm-m68k/bvme6000hw.h @@ -0,0 +1,150 @@ +#ifndef _M68K_BVME6000HW_H_ +#define _M68K_BVME6000HW_H_ + +#include <asm/irq.h> + +/* + * PIT structure + */ + +#define BVME_PIT_BASE 0xffa00000 + +typedef struct { + unsigned char + pad_a[3], pgcr, + pad_b[3], psrr, + pad_c[3], paddr, + pad_d[3], pbddr, + pad_e[3], pcddr, + pad_f[3], pivr, + pad_g[3], pacr, + pad_h[3], pbcr, + pad_i[3], padr, + pad_j[3], pbdr, + pad_k[3], paar, + pad_l[3], pbar, + pad_m[3], pcdr, + pad_n[3], psr, + pad_o[3], res1, + pad_p[3], res2, + pad_q[3], tcr, + pad_r[3], tivr, + pad_s[3], res3, + pad_t[3], cprh, + pad_u[3], cprm, + pad_v[3], cprl, + pad_w[3], res4, + pad_x[3], crh, + pad_y[3], crm, + pad_z[3], crl, + pad_A[3], tsr, + pad_B[3], res5; +} PitRegs_t, *PitRegsPtr; + +#define bvmepit ((*(volatile PitRegsPtr)(BVME_PIT_BASE))) + +#define BVME_RTC_BASE 0xff900000 + +typedef struct { + unsigned char + pad_a[3], msr, + pad_b[3], t0cr_rtmr, + pad_c[3], t1cr_omr, + pad_d[3], pfr_icr0, + pad_e[3], irr_icr1, + pad_f[3], bcd_tenms, + pad_g[3], bcd_sec, + pad_h[3], bcd_min, + pad_i[3], bcd_hr, + pad_j[3], bcd_dom, + pad_k[3], bcd_mth, + pad_l[3], bcd_year, + pad_m[3], bcd_ujcc, + pad_n[3], bcd_hjcc, + pad_o[3], bcd_dow, + pad_p[3], t0lsb, + pad_q[3], t0msb, + pad_r[3], t1lsb, + pad_s[3], t1msb, + pad_t[3], cmp_sec, + pad_u[3], cmp_min, + pad_v[3], cmp_hr, + pad_w[3], cmp_dom, + pad_x[3], cmp_mth, + pad_y[3], cmp_dow, + pad_z[3], sav_sec, + pad_A[3], sav_min, + pad_B[3], sav_hr, + pad_C[3], sav_dom, + pad_D[3], sav_mth, + pad_E[3], ram, + pad_F[3], test; +} RtcRegs_t, *RtcPtr_t; + + +#define BVME_I596_BASE 0xff100000 + +#define BVME_ETHIRQ_REG 0xff20000b + +#define BVME_LOCAL_IRQ_STAT 0xff20000f + +#define BVME_ETHERR 0x02 +#define BVME_ABORT_STATUS 0x08 + +#define BVME_NCR53C710_BASE 0xff000000 + +#define BVME_SCC_A_ADDR 0xffb0000b +#define BVME_SCC_B_ADDR 0xffb00003 +#define BVME_SCC_RTxC 7372800 + +#define BVME_CONFIG_REG 0xff500003 + +#define config_reg_ptr (volatile unsigned char *)BVME_CONFIG_REG + +#define BVME_CONFIG_SW1 0x08 +#define BVME_CONFIG_SW2 0x04 +#define BVME_CONFIG_SW3 0x02 +#define BVME_CONFIG_SW4 0x01 + + +#define BVME_IRQ_TYPE_PRIO 0 + +#define BVME_IRQ_PRN 0x54 +#define BVME_IRQ_I596 0x1a +#define BVME_IRQ_SCSI 0x1b +#define BVME_IRQ_TIMER 0x59 +#define BVME_IRQ_RTC 0x1e +#define BVME_IRQ_ABORT 0x1f + +/* SCC interrupts */ +#define BVME_IRQ_SCC_BASE 0x40 +#define BVME_IRQ_SCCB_TX 0x40 +#define BVME_IRQ_SCCB_STAT 0x42 +#define BVME_IRQ_SCCB_RX 0x44 +#define BVME_IRQ_SCCB_SPCOND 0x46 +#define BVME_IRQ_SCCA_TX 0x48 +#define BVME_IRQ_SCCA_STAT 0x4a +#define BVME_IRQ_SCCA_RX 0x4c +#define BVME_IRQ_SCCA_SPCOND 0x4e + +/* Address control registers */ + +#define BVME_ACR_A32VBA 0xff400003 +#define BVME_ACR_A32MSK 0xff410003 +#define BVME_ACR_A24VBA 0xff420003 +#define BVME_ACR_A24MSK 0xff430003 +#define BVME_ACR_A16VBA 0xff440003 +#define BVME_ACR_A32LBA 0xff450003 +#define BVME_ACR_A24LBA 0xff460003 +#define BVME_ACR_ADDRCTL 0xff470003 + +#define bvme_acr_a32vba *(volatile unsigned char *)BVME_ACR_A32VBA +#define bvme_acr_a32msk *(volatile unsigned char *)BVME_ACR_A32MSK +#define bvme_acr_a24vba *(volatile unsigned char *)BVME_ACR_A24VBA +#define bvme_acr_a24msk *(volatile unsigned char *)BVME_ACR_A24MSK +#define bvme_acr_a16vba *(volatile unsigned char *)BVME_ACR_A16VBA +#define bvme_acr_a32lba *(volatile unsigned char *)BVME_ACR_A32LBA +#define bvme_acr_a24lba *(volatile unsigned char *)BVME_ACR_A24LBA +#define bvme_acr_addrctl *(volatile unsigned char *)BVME_ACR_ADDRCTL + +#endif diff --git a/include/asm-m68k/byteorder.h b/include/asm-m68k/byteorder.h new file mode 100644 index 000000000000..81d420b35c80 --- /dev/null +++ b/include/asm-m68k/byteorder.h @@ -0,0 +1,25 @@ +#ifndef _M68K_BYTEORDER_H +#define _M68K_BYTEORDER_H + +#include <asm/types.h> +#include <linux/compiler.h> + +#ifdef __GNUC__ + +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 val) +{ + __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); + return val; +} +#define __arch__swab32(x) ___arch__swab32(x) + +#endif + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#include <linux/byteorder/big_endian.h> + +#endif /* _M68K_BYTEORDER_H */ diff --git a/include/asm-m68k/cache.h b/include/asm-m68k/cache.h new file mode 100644 index 000000000000..6161fd3d8600 --- /dev/null +++ b/include/asm-m68k/cache.h @@ -0,0 +1,13 @@ +/* + * include/asm-m68k/cache.h + */ +#ifndef __ARCH_M68K_CACHE_H +#define __ARCH_M68K_CACHE_H + +/* bytes per L1 cache line */ +#define L1_CACHE_SHIFT 4 +#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT) + +#define L1_CACHE_SHIFT_MAX 4 /* largest L1 which this arch supports */ + +#endif diff --git a/include/asm-m68k/cachectl.h b/include/asm-m68k/cachectl.h new file mode 100644 index 000000000000..525978e959e3 --- /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/cacheflush.h b/include/asm-m68k/cacheflush.h new file mode 100644 index 000000000000..e4773946f10d --- /dev/null +++ b/include/asm-m68k/cacheflush.h @@ -0,0 +1,149 @@ +#ifndef _M68K_CACHEFLUSH_H +#define _M68K_CACHEFLUSH_H + +#include <linux/mm.h> + +/* + * Cache handling functions + */ + +#define flush_icache() \ +({ \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__("nop\n\t" \ + ".chip 68040\n\t" \ + "cinva %%ic\n\t" \ + ".chip 68k" : ); \ + else { \ + unsigned long _tmp; \ + __asm__ __volatile__("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "id" (FLUSH_I)); \ + } \ +}) + +/* + * invalidate the cache for the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_clear(unsigned long paddr, int len); +/* + * push any dirty cache in the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_push(unsigned long paddr, int len); + +/* + * push and invalidate pages in the specified user virtual + * memory range. + */ +extern void cache_push_v(unsigned long vaddr, int len); + +/* cache code */ +#define FLUSH_I_AND_D (0x00000808) +#define FLUSH_I (0x00000008) + +/* This is needed whenever the virtual mapping of the current + process changes. */ +#define __flush_cache_all() \ +({ \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__("nop\n\t" \ + ".chip 68040\n\t" \ + "cpusha %dc\n\t" \ + ".chip 68k"); \ + else { \ + unsigned long _tmp; \ + __asm__ __volatile__("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ +}) + +#define __flush_cache_030() \ +({ \ + if (CPU_IS_020_OR_030) { \ + unsigned long _tmp; \ + __asm__ __volatile__("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ +}) + +#define flush_cache_all() __flush_cache_all() + +#define flush_cache_vmap(start, end) flush_cache_all() +#define flush_cache_vunmap(start, end) flush_cache_all() + +static inline void flush_cache_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + __flush_cache_030(); +} + +/* flush_cache_range/flush_cache_page must be macros to avoid + a dependency on linux/mm.h, which includes this file... */ +static inline void flush_cache_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end) +{ + if (vma->vm_mm == current->mm) + __flush_cache_030(); +} + +static inline void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) +{ + if (vma->vm_mm == current->mm) + __flush_cache_030(); +} + + +/* Push the page at kernel virtual address and clear the icache */ +/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ +static inline void __flush_page_to_ram(void *vaddr) +{ + if (CPU_IS_040_OR_060) { + __asm__ __volatile__("nop\n\t" + ".chip 68040\n\t" + "cpushp %%bc,(%0)\n\t" + ".chip 68k" + : : "a" (__pa(vaddr))); + } else { + unsigned long _tmp; + __asm__ __volatile__("movec %%cacr,%0\n\t" + "orw %1,%0\n\t" + "movec %0,%%cacr" + : "=&d" (_tmp) + : "di" (FLUSH_I)); + } +} + +#define flush_dcache_page(page) __flush_page_to_ram(page_address(page)) +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) +#define flush_icache_page(vma, page) __flush_page_to_ram(page_address(page)) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ + } while (0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ + memcpy(dst, src, len); \ + } while (0) + +extern void flush_icache_range(unsigned long address, unsigned long endaddr); + +#endif /* _M68K_CACHEFLUSH_H */ diff --git a/include/asm-m68k/checksum.h b/include/asm-m68k/checksum.h new file mode 100644 index 000000000000..78860c20db01 --- /dev/null +++ b/include/asm-m68k/checksum.h @@ -0,0 +1,150 @@ +#ifndef _M68K_CHECKSUM_H +#define _M68K_CHECKSUM_H + +#include <linux/in6.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, 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 + */ + +extern unsigned int csum_partial_copy_from_user(const unsigned char *src, + unsigned char *dst, + int len, int sum, + int *csum_err); + +extern unsigned int csum_partial_copy_nocheck(const unsigned char *src, + unsigned 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; + unsigned long tmp; + + __asm__ ("subqw #1,%2\n" + "1:\t" + "movel %1@+,%3\n\t" + "addxl %3,%0\n\t" + "dbra %2,1b\n\t" + "movel %0,%3\n\t" + "swap %3\n\t" + "addxw %3,%0\n\t" + "clrw %3\n\t" + "addxw %3,%0\n\t" + : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp) + : "0" (sum), "1" (iph), "2" (ihl) + : "memory"); + 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" (tmp)); + return ~sum; +} + + +static inline unsigned int +csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, + unsigned short proto, unsigned int sum) +{ + __asm__ ("addl %2,%0\n\t" + "addxl %3,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=d" (saddr) + : "g" (daddr), "1" (saddr), "d" (len + proto), + "0" (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) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,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)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ unsigned short int +csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, + __u32 len, unsigned short proto, unsigned int sum) +{ + register unsigned long tmp; + __asm__("addl %2@,%0\n\t" + "movel %2@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(12),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@,%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(12),%1\n\t" + "addxl %1,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=&d" (tmp) + : "a" (saddr), "a" (daddr), "d" (len + proto), + "0" (sum)); + + return csum_fold(sum); +} + +#endif /* _M68K_CHECKSUM_H */ diff --git a/include/asm-m68k/contregs.h b/include/asm-m68k/contregs.h new file mode 100644 index 000000000000..1e233e7d191e --- /dev/null +++ b/include/asm-m68k/contregs.h @@ -0,0 +1,4 @@ +#ifndef _M68K_CONTREGS_H +#define _M68K_CONTREGS_H +#include <asm-sparc/contregs.h> +#endif /* _M68K_CONTREGS_H */ diff --git a/include/asm-m68k/cputime.h b/include/asm-m68k/cputime.h new file mode 100644 index 000000000000..c79c5e892305 --- /dev/null +++ b/include/asm-m68k/cputime.h @@ -0,0 +1,6 @@ +#ifndef __M68K_CPUTIME_H +#define __M68K_CPUTIME_H + +#include <asm-generic/cputime.h> + +#endif /* __M68K_CPUTIME_H */ diff --git a/include/asm-m68k/current.h b/include/asm-m68k/current.h new file mode 100644 index 000000000000..8de8f8ceda61 --- /dev/null +++ b/include/asm-m68k/current.h @@ -0,0 +1,6 @@ +#ifndef _M68K_CURRENT_H +#define _M68K_CURRENT_H + +register struct task_struct *current __asm__("%a2"); + +#endif /* !(_M68K_CURRENT_H) */ diff --git a/include/asm-m68k/delay.h b/include/asm-m68k/delay.h new file mode 100644 index 000000000000..5ed92851bc6f --- /dev/null +++ b/include/asm-m68k/delay.h @@ -0,0 +1,57 @@ +#ifndef _M68K_DELAY_H +#define _M68K_DELAY_H + +#include <asm/param.h> + +/* + * Copyright (C) 1994 Hamish Macdonald + * + * Delay routines, using a pre-computed "loops_per_jiffy" value. + */ + +static inline void __delay(unsigned long loops) +{ + __asm__ __volatile__ ("1: subql #1,%0; jcc 1b" + : "=d" (loops) : "0" (loops)); +} + +extern void __bad_udelay(void); + +/* + * 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 + * first constant multiplications gets optimized away if the delay is + * a constant) + */ +static inline void __const_udelay(unsigned long xloops) +{ + unsigned long tmp; + + __asm__ ("mulul %2,%0:%1" + : "=d" (xloops), "=d" (tmp) + : "d" (xloops), "1" (loops_per_jiffy)); + __delay(xloops * HZ); +} + +static inline void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * 4295); /* 2**32 / 1000000 */ +} + +#define udelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 4295)) : \ + __udelay(n)) + +static 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/div64.h b/include/asm-m68k/div64.h new file mode 100644 index 000000000000..9f65de1a2480 --- /dev/null +++ b/include/asm-m68k/div64.h @@ -0,0 +1,26 @@ +#ifndef _M68K_DIV64_H +#define _M68K_DIV64_H + +/* n = n / base; return rem; */ + +#define do_div(n, base) ({ \ + union { \ + unsigned long n32[2]; \ + unsigned long long n64; \ + } __n; \ + unsigned long __rem, __upper; \ + \ + __n.n64 = (n); \ + if ((__upper = __n.n32[0])) { \ + asm ("divul.l %2,%1:%0" \ + : "=d" (__n.n32[0]), "=d" (__upper) \ + : "d" (base), "0" (__n.n32[0])); \ + } \ + asm ("divu.l %2,%1:%0" \ + : "=d" (__n.n32[1]), "=d" (__rem) \ + : "d" (base), "1" (__upper), "0" (__n.n32[1])); \ + (n) = __n.n64; \ + __rem; \ +}) + +#endif /* _M68K_DIV64_H */ diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h new file mode 100644 index 000000000000..b1920c703d82 --- /dev/null +++ b/include/asm-m68k/dma-mapping.h @@ -0,0 +1,12 @@ +#ifndef _M68K_DMA_MAPPING_H +#define _M68K_DMA_MAPPING_H + +#include <linux/config.h> + +#ifdef CONFIG_PCI +#include <asm-generic/dma-mapping.h> +#else +#include <asm-generic/dma-mapping-broken.h> +#endif + +#endif /* _M68K_DMA_MAPPING_H */ diff --git a/include/asm-m68k/dma.h b/include/asm-m68k/dma.h new file mode 100644 index 000000000000..d5266a886226 --- /dev/null +++ b/include/asm-m68k/dma.h @@ -0,0 +1,21 @@ +#ifndef _M68K_DMA_H +#define _M68K_DMA_H 1 + +#include <linux/config.h> + +/* it's useless on the m68k, but unfortunately needed by the new + bootmem allocator (but this should do it for this) */ +#define MAX_DMA_ADDRESS PAGE_OFFSET + +#define MAX_DMA_CHANNELS 8 + +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif + +#endif /* _M68K_DMA_H */ diff --git a/include/asm-m68k/dsp56k.h b/include/asm-m68k/dsp56k.h new file mode 100644 index 000000000000..ab3dd33e23a1 --- /dev/null +++ b/include/asm-m68k/dsp56k.h @@ -0,0 +1,35 @@ +/* + * linux/include/asm-m68k/dsp56k.h - defines and declarations for + * DSP56k device driver + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * 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. + */ + + +/* Used for uploading DSP binary code */ +struct dsp56k_upload { + int len; + char *bin; +}; + +/* For the DSP host flags */ +struct dsp56k_host_flags { + int dir; /* Bit field. 1 = write output bit, 0 = do nothing. + * 0x0000 means reading only, 0x0011 means + * writing the bits stored in `out' on HF0 and HF1. + * Note that HF2 and HF3 can only be read. + */ + int out; /* Bit field like above. */ + int status; /* Host register's current state is returned */ +}; + +/* ioctl command codes */ +#define DSP56K_UPLOAD 1 /* Upload DSP binary program */ +#define DSP56K_SET_TX_WSIZE 2 /* Host transmit word size (1-4) */ +#define DSP56K_SET_RX_WSIZE 3 /* Host receive word size (1-4) */ +#define DSP56K_HOST_FLAGS 4 /* Host flag registers */ +#define DSP56K_HOST_CMD 5 /* Trig Host Command (0-31) */ diff --git a/include/asm-m68k/dvma.h b/include/asm-m68k/dvma.h new file mode 100644 index 000000000000..5978f87b0a8a --- /dev/null +++ b/include/asm-m68k/dvma.h @@ -0,0 +1,243 @@ +/* $Id: dvma.h,v 1.4 1999/03/27 20:23:41 tsbogend Exp $ + * include/asm-m68k/dma.h + * + * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu) + * + * Hacked to fit Sun3x needs by Thomas Bogendoerfer + */ + +#ifndef __M68K_DVMA_H +#define __M68K_DVMA_H + +#include <linux/config.h> + +#define DVMA_PAGE_SHIFT 13 +#define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT) +#define DVMA_PAGE_MASK (~(DVMA_PAGE_SIZE-1)) +#define DVMA_PAGE_ALIGN(addr) (((addr)+DVMA_PAGE_SIZE-1)&DVMA_PAGE_MASK) + +extern void dvma_init(void); +extern int dvma_map_iommu(unsigned long kaddr, unsigned long baddr, + int len); + +#define dvma_malloc(x) dvma_malloc_align(x, 0) +#define dvma_map(x, y) dvma_map_align(x, y, 0) +#define dvma_map_vme(x, y) (dvma_map(x, y) & 0xfffff) +#define dvma_map_align_vme(x, y, z) (dvma_map_align (x, y, z) & 0xfffff) +extern unsigned long dvma_map_align(unsigned long kaddr, int len, + int align); +extern void *dvma_malloc_align(unsigned long len, unsigned long align); + +extern void dvma_unmap(void *baddr); +extern void dvma_free(void *vaddr); + + +#ifdef CONFIG_SUN3 +/* sun3 dvma page support */ + +/* memory and pmegs potentially reserved for dvma */ +#define DVMA_PMEG_START 10 +#define DVMA_PMEG_END 16 +#define DVMA_START 0xf00000 +#define DVMA_END 0xfe0000 +#define DVMA_SIZE (DVMA_END-DVMA_START) +#define IOMMU_TOTAL_ENTRIES 128 +#define IOMMU_ENTRIES 120 + +/* empirical kludge -- dvma regions only seem to work right on 0x10000 + byte boundaries */ +#define DVMA_REGION_SIZE 0x10000 +#define DVMA_ALIGN(addr) (((addr)+DVMA_REGION_SIZE-1) & \ + ~(DVMA_REGION_SIZE-1)) + +/* virt <-> phys conversions */ +#define dvma_vtop(x) ((unsigned long)(x) & 0xffffff) +#define dvma_ptov(x) ((unsigned long)(x) | 0xf000000) +#define dvma_vtovme(x) ((unsigned long)(x) & 0x00fffff) +#define dvma_vmetov(x) ((unsigned long)(x) | 0xff00000) +#define dvma_vtob(x) dvma_vtop(x) +#define dvma_btov(x) dvma_ptov(x) + +static inline int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, + int len) +{ + return 0; +} + +extern unsigned long dvma_page(unsigned long kaddr, unsigned long vaddr); + +#else /* Sun3x */ + +/* sun3x dvma page support */ + +#define DVMA_START 0x0 +#define DVMA_END 0xf00000 +#define DVMA_SIZE (DVMA_END-DVMA_START) +#define IOMMU_TOTAL_ENTRIES 2048 +/* the prom takes the top meg */ +#define IOMMU_ENTRIES (IOMMU_TOTAL_ENTRIES - 0x80) + +#define dvma_vtob(x) ((unsigned long)(x) & 0x00ffffff) +#define dvma_btov(x) ((unsigned long)(x) | 0xff000000) + +extern int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, int len); + + + +/* everything below this line is specific to dma used for the onboard + ESP scsi on sun3x */ + +/* Structure to describe the current status of DMA registers on the Sparc */ +struct sparc_dma_registers { + __volatile__ unsigned long cond_reg; /* DMA condition register */ + __volatile__ unsigned long st_addr; /* Start address of this transfer */ + __volatile__ unsigned long cnt; /* How many bytes to transfer */ + __volatile__ unsigned long dma_test; /* DMA test register */ +}; + +/* DVMA chip revisions */ +enum dvma_rev { + dvmarev0, + dvmaesc1, + dvmarev1, + dvmarev2, + dvmarev3, + dvmarevplus, + dvmahme +}; + +#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1) + +/* Linux DMA information structure, filled during probe. */ +struct Linux_SBus_DMA { + struct Linux_SBus_DMA *next; + struct linux_sbus_device *SBus_dev; + struct sparc_dma_registers *regs; + + /* Status, misc info */ + int node; /* Prom node for this DMA device */ + int running; /* Are we doing DMA now? */ + int allocated; /* Are we "owned" by anyone yet? */ + + /* Transfer information. */ + unsigned long addr; /* Start address of current transfer */ + int nbytes; /* Size of current transfer */ + int realbytes; /* For splitting up large transfers, etc. */ + + /* DMA revision */ + enum dvma_rev revision; +}; + +extern struct Linux_SBus_DMA *dma_chain; + +/* Broken hardware... */ +#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1) +#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1) + +/* Fields in the cond_reg register */ +/* First, the version identification bits */ +#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */ +#define DMA_VERS0 0x00000000 /* Sunray DMA version */ +#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */ +#define DMA_VERS1 0x80000000 /* DMA rev 1 */ +#define DMA_VERS2 0xa0000000 /* DMA rev 2 */ +#define DMA_VERHME 0xb0000000 /* DMA hme gate array */ +#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */ + +#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */ +#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */ +#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */ +#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */ +#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */ +#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */ +#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */ +#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */ +#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */ +#define DMA_ST_WRITE 0x00000100 /* write from device to memory */ +#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */ +#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */ +#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */ +#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */ +#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */ +#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */ +#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */ +#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */ +#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */ +#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */ +#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */ +#define DMA_E_BURST8 0x00040000 /* ENET: SBUS r/w burst size */ +#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */ +#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */ +#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */ +#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */ +#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */ +#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */ +#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */ +#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */ +#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */ +#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */ +#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */ +#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */ +#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */ +#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */ +#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */ + +/* Values describing the burst-size property from the PROM */ +#define DMA_BURST1 0x01 +#define DMA_BURST2 0x02 +#define DMA_BURST4 0x04 +#define DMA_BURST8 0x08 +#define DMA_BURST16 0x10 +#define DMA_BURST32 0x20 +#define DMA_BURST64 0x40 +#define DMA_BURSTBITS 0x7f + +/* Determine highest possible final transfer address given a base */ +#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL)) + +/* Yes, I hack a lot of elisp in my spare time... */ +#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR)) +#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))) +#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE)) +#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE))) +#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB))) +#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB))) +#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV)) +#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr)) +#define DMA_BEGINDMA_W(regs) \ + ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB)))) +#define DMA_BEGINDMA_R(regs) \ + ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE))))) + +/* For certain DMA chips, we need to disable ints upon irq entry + * and turn them back on when we are done. So in any ESP interrupt + * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT + * when leaving the handler. You have been warned... + */ +#define DMA_IRQ_ENTRY(dma, dregs) do { \ + if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \ + } while (0) + +#define DMA_IRQ_EXIT(dma, dregs) do { \ + if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \ + } while(0) + +/* Reset the friggin' thing... */ +#define DMA_RESET(dma) do { \ + struct sparc_dma_registers *regs = dma->regs; \ + /* Let the current FIFO drain itself */ \ + sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \ + /* Reset the logic */ \ + regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \ + __delay(400); /* let the bits set ;) */ \ + regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \ + sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \ + /* Enable FAST transfers if available */ \ + if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \ + dma->running = 0; \ +} while(0) + + +#endif /* !CONFIG_SUN3 */ + +#endif /* !(__M68K_DVMA_H) */ diff --git a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h new file mode 100644 index 000000000000..38bf8347f14d --- /dev/null +++ b/include/asm-m68k/elf.h @@ -0,0 +1,122 @@ +#ifndef __ASMm68k_ELF_H +#define __ASMm68k_ELF_H + +/* + * ELF register definitions.. + */ + +#include <linux/config.h> +#include <asm/ptrace.h> +#include <asm/user.h> + +/* + * 68k ELF relocation types + */ +#define R_68K_NONE 0 +#define R_68K_32 1 +#define R_68K_16 2 +#define R_68K_8 3 +#define R_68K_PC32 4 +#define R_68K_PC16 5 +#define R_68K_PC8 6 +#define R_68K_GOT32 7 +#define R_68K_GOT16 8 +#define R_68K_GOT8 9 +#define R_68K_GOT32O 10 +#define R_68K_GOT16O 11 +#define R_68K_GOT8O 12 +#define R_68K_PLT32 13 +#define R_68K_PLT16 14 +#define R_68K_PLT8 15 +#define R_68K_PLT32O 16 +#define R_68K_PLT16O 17 +#define R_68K_PLT8O 18 +#define R_68K_COPY 19 +#define R_68K_GLOB_DAT 20 +#define R_68K_JMP_SLOT 21 +#define R_68K_RELATIVE 22 + +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)->e_machine == 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, load_addr) _r->a1 = 0 + +#define USE_ELF_CORE_DUMP +#ifndef CONFIG_SUN3 +#define ELF_EXEC_PAGESIZE 4096 +#else +#define ELF_EXEC_PAGESIZE 8192 +#endif + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#ifndef CONFIG_SUN3 +#define ELF_ET_DYN_BASE 0xD0000000UL +#else +#define ELF_ET_DYN_BASE 0x0D800000UL +#endif + +#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[9] = regs->a2; \ + 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[10] = sw->a3; \ + pr_reg[11] = sw->a4; \ + pr_reg[12] = sw->a5; \ + pr_reg[13] = sw->a6; \ + } + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +#define ELF_HWCAP (0) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) +#endif + +#endif diff --git a/include/asm-m68k/entry.h b/include/asm-m68k/entry.h new file mode 100644 index 000000000000..0396495cd97d --- /dev/null +++ b/include/asm-m68k/entry.h @@ -0,0 +1,138 @@ +#ifndef __M68K_ENTRY_H +#define __M68K_ENTRY_H + +#include <linux/config.h> +#include <asm/setup.h> +#include <asm/page.h> + +/* + * Stack layout in 'ret_from_exception': + * + * This allows access to the syscall arguments in registers d1-d5 + * + * 0(sp) - d1 + * 4(sp) - d2 + * 8(sp) - d3 + * C(sp) - d4 + * 10(sp) - d5 + * 14(sp) - a0 + * 18(sp) - a1 + * 1C(sp) - a2 + * 20(sp) - d0 + * 24(sp) - orig_d0 + * 28(sp) - stack adjustment + * 2C(sp) - sr + * 2E(sp) - pc + * 32(sp) - format & vector + */ + +/* + * 97/05/14 Andreas: Register %a2 is now set to the current task throughout + * the whole kernel. + */ + +/* the following macro is used when enabling interrupts */ +#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES) + /* block out HSYNC on the atari */ +#define ALLOWINT (~0x400) +#define MAX_NOINT_IPL 3 +#else + /* portable version */ +#define ALLOWINT (~0x700) +#define MAX_NOINT_IPL 0 +#endif /* machine compilation types */ + +#ifdef __ASSEMBLY__ + +#define curptr a2 + +LFLUSH_I_AND_D = 0x00000808 +LSIGTRAP = 5 + +/* process bits for task_struct.ptrace */ +PT_TRACESYS_OFF = 3 +PT_TRACESYS_BIT = 1 +PT_PTRACED_OFF = 3 +PT_PTRACED_BIT = 0 +PT_DTRACE_OFF = 3 +PT_DTRACE_BIT = 2 + +#define SAVE_ALL_INT save_all_int +#define SAVE_ALL_SYS save_all_sys +#define RESTORE_ALL restore_all +/* + * This defines the normal kernel pt-regs layout. + * + * regs a3-a6 and d6-d7 are preserved by C code + * the kernel doesn't mess with usp unless it needs to + */ + +/* + * a -1 in the orig_d0 field signifies + * that the stack frame is NOT for syscall + */ +.macro save_all_int + clrl %sp@- | stk_adj + pea -1:w | orig d0 + movel %d0,%sp@- | d0 + moveml %d1-%d5/%a0-%a1/%curptr,%sp@- +.endm + +.macro save_all_sys + clrl %sp@- | stk_adj + movel %d0,%sp@- | orig d0 + movel %d0,%sp@- | d0 + moveml %d1-%d5/%a0-%a1/%curptr,%sp@- +.endm + +.macro restore_all + moveml %sp@+,%a0-%a1/%curptr/%d1-%d5 + movel %sp@+,%d0 + addql #4,%sp | orig d0 + addl %sp@+,%sp | stk adj + rte +.endm + +#define SWITCH_STACK_SIZE (6*4+4) /* includes return address */ + +#define SAVE_SWITCH_STACK save_switch_stack +#define RESTORE_SWITCH_STACK restore_switch_stack +#define GET_CURRENT(tmp) get_current tmp + +.macro save_switch_stack + moveml %a3-%a6/%d6-%d7,%sp@- +.endm + +.macro restore_switch_stack + moveml %sp@+,%a3-%a6/%d6-%d7 +.endm + +.macro get_current reg=%d0 + movel %sp,\reg + andw #-THREAD_SIZE,\reg + movel \reg,%curptr + movel %curptr@,%curptr +.endm + +#else /* C source */ + +#define STR(X) STR1(X) +#define STR1(X) #X + +#define PT_OFF_ORIG_D0 0x24 +#define PT_OFF_FORMATVEC 0x32 +#define PT_OFF_SR 0x2C +#define SAVE_ALL_INT \ + "clrl %%sp@-;" /* stk_adj */ \ + "pea -1:w;" /* orig d0 = -1 */ \ + "movel %%d0,%%sp@-;" /* d0 */ \ + "moveml %%d1-%%d5/%%a0-%%a2,%%sp@-" +#define GET_CURRENT(tmp) \ + "movel %%sp,"#tmp"\n\t" \ + "andw #-"STR(THREAD_SIZE)","#tmp"\n\t" \ + "movel "#tmp",%%a2\n\t" \ + "movel %%a2@,%%a2" + +#endif + +#endif /* __M68K_ENTRY_H */ diff --git a/include/asm-m68k/errno.h b/include/asm-m68k/errno.h new file mode 100644 index 000000000000..0d4e188d6ef6 --- /dev/null +++ b/include/asm-m68k/errno.h @@ -0,0 +1,6 @@ +#ifndef _M68K_ERRNO_H +#define _M68K_ERRNO_H + +#include <asm-generic/errno.h> + +#endif /* _M68K_ERRNO_H */ diff --git a/include/asm-m68k/fbio.h b/include/asm-m68k/fbio.h new file mode 100644 index 000000000000..c17edf8c7bc4 --- /dev/null +++ b/include/asm-m68k/fbio.h @@ -0,0 +1 @@ +#include <asm-sparc/fbio.h> diff --git a/include/asm-m68k/fcntl.h b/include/asm-m68k/fcntl.h new file mode 100644 index 000000000000..0d4212983a33 --- /dev/null +++ b/include/asm-m68k/fcntl.h @@ -0,0 +1,87 @@ +#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 O_DIRECTORY 040000 /* must be a directory */ +#define O_NOFOLLOW 0100000 /* don't follow links */ +#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0400000 +#define O_NOATIME 01000000 + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get close_on_exec */ +#define F_SETFD 2 /* set/clear close_on_exec */ +#define F_GETFL 3 /* get file->f_flags */ +#define F_SETFL 4 /* set file->f_flags */ +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ +#define F_SETSIG 10 /* for sockets. */ +#define F_GETSIG 11 /* for sockets. */ + +#define F_GETLK64 12 /* using 'struct flock64' */ +#define F_SETLK64 13 +#define F_SETLKW64 14 + +/* 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 */ + +/* for leases */ +#define F_INPROGRESS 16 + +/* 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 */ + +#define LOCK_MAND 32 /* This is a mandatory flock */ +#define LOCK_READ 64 /* ... Which allows concurrent read operations */ +#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */ +#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +struct flock64 { + short l_type; + short l_whence; + loff_t l_start; + loff_t l_len; + pid_t l_pid; +}; + +#define F_LINUX_SPECIFIC_BASE 1024 +#endif /* _M68K_FCNTL_H */ diff --git a/include/asm-m68k/floppy.h b/include/asm-m68k/floppy.h new file mode 100644 index 000000000000..c6e708dd9f62 --- /dev/null +++ b/include/asm-m68k/floppy.h @@ -0,0 +1,259 @@ +/* + * Implementation independent bits of the Floppy driver. + * + * much of this file is derived from what was originally the Q40 floppy driver. + * + * 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. + * + * Copyright (C) 1999, 2000, 2001 + * + * Sun3x support added 2/4/2000 Sam Creasey (sammy@sammy.net) + * + */ + +#include <asm/io.h> + +#include <linux/vmalloc.h> + +asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id, + struct pt_regs *regs); + +/* constants... */ + +#undef MAX_DMA_ADDRESS +#define MAX_DMA_ADDRESS 0x00 /* nothing like that */ + + +/* + * Again, the CMOS information doesn't work on m68k.. + */ +#define FLOPPY0_TYPE (MACH_IS_Q40 ? 6 : 4) +#define FLOPPY1_TYPE 0 + +#define FLOPPY_MOTOR_MASK 0xf0 + + +/* basically PC init + set use_virtual_dma */ +#define FDC1 m68k_floppy_init() + +#define N_FDC 1 +#define N_DRIVE 8 + + +/* vdma globals adapted from asm-i386/floppy.h */ + +static int virtual_dma_count=0; +static int virtual_dma_residue=0; +static char *virtual_dma_addr=0; +static int virtual_dma_mode=0; +static int doing_pdma=0; + +#include <asm/sun3xflop.h> + +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + + +static __inline__ unsigned char fd_inb(int port) +{ + if(MACH_IS_Q40) + return inb_p(port); + else if(MACH_IS_SUN3X) + return sun3x_82072_fd_inb(port); + return 0; +} + +static __inline__ void fd_outb(unsigned char value, int port) +{ + if(MACH_IS_Q40) + outb_p(value, port); + else if(MACH_IS_SUN3X) + sun3x_82072_fd_outb(value, port); +} + + +static int fd_request_irq(void) +{ + if(MACH_IS_Q40) + return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT, + "floppy", floppy_hardint); + else if(MACH_IS_SUN3X) + return sun3xflop_request_irq(); + return -ENXIO; +} + +static void fd_free_irq(void) +{ + if(MACH_IS_Q40) + free_irq(FLOPPY_IRQ, floppy_hardint); +} + +#define fd_request_dma() vdma_request_dma(FLOPPY_DMA,"floppy") +#define fd_get_dma_residue() vdma_get_dma_residue(FLOPPY_DMA) +#define fd_dma_mem_alloc(size) vdma_mem_alloc(size) +#define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io) + +#define fd_enable_irq() /* nothing... */ +#define fd_disable_irq() /* nothing... */ + +#define fd_free_dma() /* nothing */ + +/* No 64k boundary crossing problems on Q40 - no DMA at all */ +#define CROSS_64KB(a,s) (0) + +#define DMA_MODE_READ 0x44 /* i386 look-alike */ +#define DMA_MODE_WRITE 0x48 + + +static int m68k_floppy_init(void) +{ + use_virtual_dma =1; + can_use_virtual_dma = 1; + + + if (MACH_IS_Q40) + return 0x3f0; + else if(MACH_IS_SUN3X) + return sun3xflop_init(); + else + return -1; +} + + +static int vdma_request_dma(unsigned int dmanr, const char * device_id) +{ + return 0; +} + + +static int vdma_get_dma_residue(unsigned int dummy) +{ + return virtual_dma_count + virtual_dma_residue; +} + + +static unsigned long vdma_mem_alloc(unsigned long size) +{ + return (unsigned long) vmalloc(size); + +} + +static void _fd_dma_mem_free(unsigned long addr, unsigned long size) +{ + vfree((void *)addr); +} +#define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size) + + +/* choose_dma_mode ???*/ + +static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) +{ + doing_pdma = 1; + virtual_dma_port = (MACH_IS_Q40 ? io : 0); + virtual_dma_mode = (mode == DMA_MODE_WRITE); + virtual_dma_addr = addr; + virtual_dma_count = size; + virtual_dma_residue = 0; + return 0; +} + + + +static void fd_disable_dma(void) +{ + doing_pdma = 0; + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; +} + + + +/* this is the only truly Q40 specific function */ + +asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id, + struct pt_regs *regs) +{ + register unsigned char st; + +#undef TRACE_FLPY_INT +#define NO_FLOPPY_ASSEMBLER + +#ifdef TRACE_FLPY_INT + static int calls=0; + static int bytes=0; + static int dma_wait=0; +#endif + if(!doing_pdma) { + floppy_interrupt(irq, dev_id, regs); + return IRQ_HANDLED; + } + +#ifdef TRACE_FLPY_INT + if(!calls) + bytes = virtual_dma_count; +#endif + + { + register int lcount; + register char *lptr; + + /* serve 1st byte fast: */ + + st=1; + for(lcount=virtual_dma_count, lptr=virtual_dma_addr; + lcount; lcount--, lptr++) { + st=inb(virtual_dma_port+4) & 0xa0 ; + if(st != 0xa0) + break; + if(virtual_dma_mode) + outb_p(*lptr, virtual_dma_port+5); + else + *lptr = inb_p(virtual_dma_port+5); + } + + virtual_dma_count = lcount; + virtual_dma_addr = lptr; + st = inb(virtual_dma_port+4); + } + +#ifdef TRACE_FLPY_INT + calls++; +#endif + if(st == 0x20) + return IRQ_HANDLED; + if(!(st & 0x20)) { + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; +#ifdef TRACE_FLPY_INT + printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", + virtual_dma_count, virtual_dma_residue, calls, bytes, + dma_wait); + calls = 0; + dma_wait=0; +#endif + doing_pdma = 0; + floppy_interrupt(irq, dev_id, regs); + return IRQ_HANDLED; + } +#ifdef TRACE_FLPY_INT + if(!virtual_dma_count) + dma_wait++; +#endif + return IRQ_HANDLED; +} + +#define EXTRA_FLOPPY_PARAMS diff --git a/include/asm-m68k/fpu.h b/include/asm-m68k/fpu.h new file mode 100644 index 000000000000..3bcf85065c19 --- /dev/null +++ b/include/asm-m68k/fpu.h @@ -0,0 +1,22 @@ +#ifndef __M68K_FPU_H +#define __M68K_FPU_H + +#include <linux/config.h> + +/* + * MAX floating point unit state size (FSAVE/FRESTORE) + */ + +#if defined(CONFIG_M68020) || defined(CONFIG_M68030) +#define FPSTATESIZE (216/sizeof(unsigned char)) +#elif defined(CONFIG_M68040) +#define FPSTATESIZE (96/sizeof(unsigned char)) +#elif defined(CONFIG_M68KFPU_EMU) +#define FPSTATESIZE (28/sizeof(unsigned char)) +#elif defined(CONFIG_M68060) +#define FPSTATESIZE (12/sizeof(unsigned char)) +#else +#define FPSTATESIZE error no_cpu_type_configured +#endif + +#endif /* __M68K_FPU_H */ diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h new file mode 100644 index 000000000000..728318bf7f0e --- /dev/null +++ b/include/asm-m68k/hardirq.h @@ -0,0 +1,26 @@ +#ifndef __M68K_HARDIRQ_H +#define __M68K_HARDIRQ_H + +#include <linux/config.h> +#include <linux/threads.h> +#include <linux/cache.h> + +/* entry.S is sensitive to the offsets of these fields */ +typedef struct { + unsigned int __softirq_pending; +} ____cacheline_aligned irq_cpustat_t; + +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ + +#define HARDIRQ_BITS 8 + +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif + +#endif diff --git a/include/asm-m68k/hdreg.h b/include/asm-m68k/hdreg.h new file mode 100644 index 000000000000..5989bbc97cbf --- /dev/null +++ b/include/asm-m68k/hdreg.h @@ -0,0 +1 @@ +#warning this file is obsolete, please do not use it diff --git a/include/asm-m68k/hp300hw.h b/include/asm-m68k/hp300hw.h new file mode 100644 index 000000000000..d998ea67c19c --- /dev/null +++ b/include/asm-m68k/hp300hw.h @@ -0,0 +1,25 @@ +#ifndef _M68K_HP300HW_H +#define _M68K_HP300HW_H + +extern unsigned long hp300_model; + +/* This information was taken from NetBSD */ +#define HP_320 (0) /* 16MHz 68020+HP MMU+16K external cache */ +#define HP_330 (1) /* 16MHz 68020+68851 MMU */ +#define HP_340 (2) /* 16MHz 68030 */ +#define HP_345 (3) /* 50MHz 68030+32K external cache */ +#define HP_350 (4) /* 25MHz 68020+HP MMU+32K external cache */ +#define HP_360 (5) /* 25MHz 68030 */ +#define HP_370 (6) /* 33MHz 68030+64K external cache */ +#define HP_375 (7) /* 50MHz 68030+32K external cache */ +#define HP_380 (8) /* 25MHz 68040 */ +#define HP_385 (9) /* 33MHz 68040 */ + +#define HP_400 (10) /* 50MHz 68030+32K external cache */ +#define HP_425T (11) /* 25MHz 68040 - model 425t */ +#define HP_425S (12) /* 25MHz 68040 - model 425s */ +#define HP_425E (13) /* 25MHz 68040 - model 425e */ +#define HP_433T (14) /* 33MHz 68040 - model 433t */ +#define HP_433S (15) /* 33MHz 68040 - model 433s */ + +#endif /* _M68K_HP300HW_H */ diff --git a/include/asm-m68k/hw_irq.h b/include/asm-m68k/hw_irq.h new file mode 100644 index 000000000000..eacef0951fbf --- /dev/null +++ b/include/asm-m68k/hw_irq.h @@ -0,0 +1,6 @@ +#ifndef __ASM_M68K_HW_IRQ_H +#define __ASM_M68K_HW_IRQ_H + +/* Dummy include. */ + +#endif diff --git a/include/asm-m68k/hwtest.h b/include/asm-m68k/hwtest.h new file mode 100644 index 000000000000..402c8a4401fe --- /dev/null +++ b/include/asm-m68k/hwtest.h @@ -0,0 +1,15 @@ +/* Routines to test for presence/absence of hardware registers: + * see arch/m68k/mm/hwtest.c. + * -- PMM <pmaydell@chiark.greenend.org.uk> 05/1998 + * + * Removed __init from decls. We might want them in modules, and + * the code is tiny anyway. 16/5/98 pb + */ + +#ifndef __ASM_HWTEST_H +#define __ASM_HWTEST_H + +extern int hwreg_present(volatile void *regp); +extern int hwreg_write(volatile void *regp, unsigned short val); + +#endif diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h new file mode 100644 index 000000000000..36118fd01867 --- /dev/null +++ b/include/asm-m68k/ide.h @@ -0,0 +1,144 @@ +/* + * 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> + +#include <asm/setup.h> +#include <asm/io.h> +#include <asm/irq.h> + +#ifdef CONFIG_ATARI +#include <linux/interrupt.h> +#include <asm/atari_stdma.h> +#endif + +#ifdef CONFIG_MAC +#include <asm/macints.h> +#endif + +#ifndef MAX_HWIFS +#define MAX_HWIFS 4 /* same as the other archs */ +#endif + +/* + * Get rid of defs from io.h - ide has its private and conflicting versions + * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we + * always use the `raw' MMIO versions + */ +#undef inb +#undef inw +#undef insw +#undef inl +#undef insl +#undef outb +#undef outw +#undef outsw +#undef outl +#undef outsl +#undef readb +#undef readw +#undef readl +#undef writeb +#undef writew +#undef writel + +#define inb in_8 +#define inw in_be16 +#define insw(port, addr, n) raw_insw((u16 *)port, addr, n) +#define inl in_be32 +#define insl(port, addr, n) raw_insl((u32 *)port, addr, n) +#define outb(val, port) out_8(port, val) +#define outw(val, port) out_be16(port, val) +#define outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) +#define outl(val, port) out_be32(port, val) +#define outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) +#define readb in_8 +#define readw in_be16 +#define __ide_mm_insw(port, addr, n) raw_insw((u16 *)port, addr, n) +#define readl in_be32 +#define __ide_mm_insl(port, addr, n) raw_insl((u32 *)port, addr, n) +#define writeb(val, port) out_8(port, val) +#define writew(val, port) out_be16(port, val) +#define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) +#define writel(val, port) out_be32(port, val) +#define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) +#define insw_swapw(port, addr, n) raw_insw_swapw((u16 *)port, addr, n) +#define outsw_swapw(port, addr, n) raw_outsw_swapw((u16 *)port, addr, n) +#endif + + +/* Q40 and Atari have byteswapped IDE busses and since many interesting + * values in the identification string are text, chars and words they + * happened to be almost correct without swapping.. However *_capacity + * is needed for drives over 8 GB. RZ */ +#if defined(CONFIG_Q40) || defined(CONFIG_ATARI) +#define M68K_IDE_SWAPW (MACH_IS_Q40 || MACH_IS_ATARI) +#endif + +#ifdef CONFIG_BLK_DEV_FALCON_IDE +#define IDE_ARCH_LOCK + +extern int falconide_intr_lock; + +static __inline__ void ide_release_lock (void) +{ + if (MACH_IS_ATARI) { + if (falconide_intr_lock == 0) { + printk("ide_release_lock: bug\n"); + return; + } + falconide_intr_lock = 0; + stdma_release(); + } +} + +static __inline__ void +ide_get_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *), void *data) +{ + if (MACH_IS_ATARI) { + if (falconide_intr_lock == 0) { + if (in_interrupt() > 0) + panic( "Falcon IDE hasn't ST-DMA lock in interrupt" ); + stdma_lock(handler, data); + falconide_intr_lock = 1; + } + } +} +#endif /* CONFIG_BLK_DEV_FALCON_IDE */ + +#define IDE_ARCH_ACK_INTR +#define ide_ack_intr(hwif) ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1) + +#endif /* __KERNEL__ */ +#endif /* _M68K_IDE_H */ diff --git a/include/asm-m68k/idprom.h b/include/asm-m68k/idprom.h new file mode 100644 index 000000000000..4349eaf3cfe4 --- /dev/null +++ b/include/asm-m68k/idprom.h @@ -0,0 +1,8 @@ +#ifndef _M68K_IDPROM_H +#define _M68K_IDPROM_H +#include <asm-sparc/idprom.h> + +/* Sun3: in control space */ +#define SUN3_IDPROM_BASE 0x00000000 + +#endif /* !(_M68K_IDPROM_H) */ diff --git a/include/asm-m68k/intersil.h b/include/asm-m68k/intersil.h new file mode 100644 index 000000000000..f482902cac8a --- /dev/null +++ b/include/asm-m68k/intersil.h @@ -0,0 +1,48 @@ +#ifndef _SUN3_INTERSIL_H +#define _SUN3_INTERSIL_H +/* bits 0 and 1 */ +#define INTERSIL_FREQ_32K 0x00 +#define INTERSIL_FREQ_1M 0x01 +#define INTERSIL_FREQ_2M 0x02 +#define INTERSIL_FREQ_4M 0x03 + +/* bit 2 */ +#define INTERSIL_12H_MODE 0x00 +#define INTERSIL_24H_MODE 0x04 + +/* bit 3 */ +#define INTERSIL_STOP 0x00 +#define INTERSIL_RUN 0x08 + +/* bit 4 */ +#define INTERSIL_INT_ENABLE 0x10 +#define INTERSIL_INT_DISABLE 0x00 + +/* bit 5 */ +#define INTERSIL_MODE_NORMAL 0x00 +#define INTERSIL_MODE_TEST 0x20 + +#define INTERSIL_HZ_100_MASK 0x02 + +struct intersil_dt { + unsigned char csec; + unsigned char hour; + unsigned char minute; + unsigned char second; + unsigned char month; + unsigned char day; + unsigned char year; + unsigned char weekday; +}; + +struct intersil_7170 { + struct intersil_dt counter; + struct intersil_dt alarm; + unsigned char int_reg; + unsigned char cmd_reg; +}; + +extern volatile char* clock_va; +#define intersil_clock ((volatile struct intersil_7170 *) clock_va) +#define intersil_clear() (void)intersil_clock->int_reg +#endif diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h new file mode 100644 index 000000000000..6bb8b0d8f99d --- /dev/null +++ b/include/asm-m68k/io.h @@ -0,0 +1,376 @@ +/* + * linux/include/asm-m68k/io.h + * + * 4/1/00 RZ: - rewritten to avoid clashes between ISA/PCI and other + * IO access + * - added Q40 support + * - added skeleton for GG-II and Amiga PCMCIA + * 2/3/01 RZ: - moved a few more defs into raw_io.h + * + * inX/outX/readX/writeX should not be used by any driver unless it does + * ISA or PCI access. Other drivers should use function defined in raw_io.h + * or define its own macros on top of these. + * + * inX(),outX() are for PCI and ISA I/O + * readX(),writeX() are for PCI memory + * isa_readX(),isa_writeX() are for ISA memory + * + * moved mem{cpy,set}_*io inside CONFIG_PCI + */ + +#ifndef _IO_H +#define _IO_H + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <asm/raw_io.h> +#include <asm/virtconvert.h> + + +#ifdef CONFIG_ATARI +#include <asm/atarihw.h> +#endif + + +/* + * IO/MEM definitions for various ISA bridges + */ + + +#ifdef CONFIG_Q40 + +#define q40_isa_io_base 0xff400000 +#define q40_isa_mem_base 0xff800000 + +#define Q40_ISA_IO_B(ioaddr) (q40_isa_io_base+1+4*((unsigned long)(ioaddr))) +#define Q40_ISA_IO_W(ioaddr) (q40_isa_io_base+ 4*((unsigned long)(ioaddr))) +#define Q40_ISA_MEM_B(madr) (q40_isa_mem_base+1+4*((unsigned long)(madr))) +#define Q40_ISA_MEM_W(madr) (q40_isa_mem_base+ 4*((unsigned long)(madr))) + +#define MULTI_ISA 0 +#endif /* Q40 */ + +/* GG-II Zorro to ISA bridge */ +#ifdef CONFIG_GG2 + +extern unsigned long gg2_isa_base; +#define GG2_ISA_IO_B(ioaddr) (gg2_isa_base+1+((unsigned long)(ioaddr)*4)) +#define GG2_ISA_IO_W(ioaddr) (gg2_isa_base+ ((unsigned long)(ioaddr)*4)) +#define GG2_ISA_MEM_B(madr) (gg2_isa_base+1+(((unsigned long)(madr)*4) & 0xfffff)) +#define GG2_ISA_MEM_W(madr) (gg2_isa_base+ (((unsigned long)(madr)*4) & 0xfffff)) + +#ifndef MULTI_ISA +#define MULTI_ISA 0 +#else +#undef MULTI_ISA +#define MULTI_ISA 1 +#endif +#endif /* GG2 */ + +#ifdef CONFIG_AMIGA_PCMCIA +#include <asm/amigayle.h> + +#define AG_ISA_IO_B(ioaddr) ( GAYLE_IO+(ioaddr)+(((ioaddr)&1)*GAYLE_ODD) ) +#define AG_ISA_IO_W(ioaddr) ( GAYLE_IO+(ioaddr) ) + +#ifndef MULTI_ISA +#define MULTI_ISA 0 +#else +#undef MULTI_ISA +#define MULTI_ISA 1 +#endif +#endif /* AMIGA_PCMCIA */ + + + +#ifdef CONFIG_ISA + +#if MULTI_ISA == 0 +#undef MULTI_ISA +#endif + +#define Q40_ISA (1) +#define GG2_ISA (2) +#define AG_ISA (3) + +#if defined(CONFIG_Q40) && !defined(MULTI_ISA) +#define ISA_TYPE Q40_ISA +#define ISA_SEX 0 +#endif +#if defined(CONFIG_AMIGA_PCMCIA) && !defined(MULTI_ISA) +#define ISA_TYPE AG_ISA +#define ISA_SEX 1 +#endif +#if defined(CONFIG_GG2) && !defined(MULTI_ISA) +#define ISA_TYPE GG2_ISA +#define ISA_SEX 0 +#endif + +#ifdef MULTI_ISA +extern int isa_type; +extern int isa_sex; + +#define ISA_TYPE isa_type +#define ISA_SEX isa_sex +#endif + +/* + * define inline addr translation functions. Normally only one variant will + * be compiled in so the case statement will be optimised away + */ + +static inline u8 *isa_itb(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case Q40_ISA: return (u8 *)Q40_ISA_IO_B(addr); +#endif +#ifdef CONFIG_GG2 + case GG2_ISA: return (u8 *)GG2_ISA_IO_B(addr); +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case AG_ISA: return (u8 *)AG_ISA_IO_B(addr); +#endif + default: return 0; /* avoid warnings, just in case */ + } +} +static inline u16 *isa_itw(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case Q40_ISA: return (u16 *)Q40_ISA_IO_W(addr); +#endif +#ifdef CONFIG_GG2 + case GG2_ISA: return (u16 *)GG2_ISA_IO_W(addr); +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case AG_ISA: return (u16 *)AG_ISA_IO_W(addr); +#endif + default: return 0; /* avoid warnings, just in case */ + } +} +static inline u8 *isa_mtb(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case Q40_ISA: return (u8 *)Q40_ISA_MEM_B(addr); +#endif +#ifdef CONFIG_GG2 + case GG2_ISA: return (u8 *)GG2_ISA_MEM_B(addr); +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case AG_ISA: return (u8 *)addr; +#endif + default: return 0; /* avoid warnings, just in case */ + } +} +static inline u16 *isa_mtw(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case Q40_ISA: return (u16 *)Q40_ISA_MEM_W(addr); +#endif +#ifdef CONFIG_GG2 + case GG2_ISA: return (u16 *)GG2_ISA_MEM_W(addr); +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case AG_ISA: return (u16 *)addr; +#endif + default: return 0; /* avoid warnings, just in case */ + } +} + + +#define isa_inb(port) in_8(isa_itb(port)) +#define isa_inw(port) (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port))) +#define isa_outb(val,port) out_8(isa_itb(port),(val)) +#define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) + +#define isa_readb(p) in_8(isa_mtb((unsigned long)(p))) +#define isa_readw(p) \ + (ISA_SEX ? in_be16(isa_mtw((unsigned long)(p))) \ + : in_le16(isa_mtw((unsigned long)(p)))) +#define isa_writeb(val,p) out_8(isa_mtb((unsigned long)(p)),(val)) +#define isa_writew(val,p) \ + (ISA_SEX ? out_be16(isa_mtw((unsigned long)(p)),(val)) \ + : out_le16(isa_mtw((unsigned long)(p)),(val))) + +static inline void isa_delay(void) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case Q40_ISA: isa_outb(0,0x80); break; +#endif +#ifdef CONFIG_GG2 + case GG2_ISA: break; +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case AG_ISA: break; +#endif + default: break; /* avoid warnings */ + } +} + +#define isa_inb_p(p) ({u8 v=isa_inb(p);isa_delay();v;}) +#define isa_outb_p(v,p) ({isa_outb((v),(p));isa_delay();}) +#define isa_inw_p(p) ({u16 v=isa_inw(p);isa_delay();v;}) +#define isa_outw_p(v,p) ({isa_outw((v),(p));isa_delay();}) +#define isa_inl_p(p) ({u32 v=isa_inl(p);isa_delay();v;}) +#define isa_outl_p(v,p) ({isa_outl((v),(p));isa_delay();}) + +#define isa_insb(port, buf, nr) raw_insb(isa_itb(port), (u8 *)(buf), (nr)) +#define isa_outsb(port, buf, nr) raw_outsb(isa_itb(port), (u8 *)(buf), (nr)) + +#define isa_insw(port, buf, nr) \ + (ISA_SEX ? raw_insw(isa_itw(port), (u16 *)(buf), (nr)) : \ + raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr))) + +#define isa_outsw(port, buf, nr) \ + (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \ + raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr))) +#endif /* CONFIG_ISA */ + + +#if defined(CONFIG_ISA) && !defined(CONFIG_PCI) +#define inb isa_inb +#define inb_p isa_inb_p +#define outb isa_outb +#define outb_p isa_outb_p +#define inw isa_inw +#define inw_p isa_inw_p +#define outw isa_outw +#define outw_p isa_outw_p +#define inl isa_inw +#define inl_p isa_inw_p +#define outl isa_outw +#define outl_p isa_outw_p +#define insb isa_insb +#define insw isa_insw +#define outsb isa_outsb +#define outsw isa_outsw +#define readb isa_readb +#define readw isa_readw +#define writeb isa_writeb +#define writew isa_writew +#endif /* CONFIG_ISA */ + +#if defined(CONFIG_PCI) + +#define inl(port) in_le32(port) +#define outl(val,port) out_le32((port),(val)) +#define readl(addr) in_le32(addr) +#define writel(val,addr) out_le32((addr),(val)) + +/* those can be defined for both ISA and PCI - it won't work though */ +#define readb(addr) in_8(addr) +#define readw(addr) in_le16(addr) +#define writeb(val,addr) out_8((addr),(val)) +#define writew(val,addr) out_le16((addr),(val)) + +#define readb_relaxed(addr) readb(addr) +#define readw_relaxed(addr) readw(addr) +#define readl_relaxed(addr) readl(addr) + +#ifndef CONFIG_ISA +#define inb(port) in_8(port) +#define outb(val,port) out_8((port),(val)) +#define inw(port) in_le16(port) +#define outw(val,port) out_le16((port),(val)) + +#else +/* + * kernel with both ISA and PCI compiled in, those have + * conflicting defs for in/out. Simply consider port < 1024 + * ISA and everything else PCI. read,write not defined + * in this case + */ +#define inb(port) ((port)<1024 ? isa_inb(port) : in_8(port)) +#define inb_p(port) ((port)<1024 ? isa_inb_p(port) : in_8(port)) +#define inw(port) ((port)<1024 ? isa_inw(port) : in_le16(port)) +#define inw_p(port) ((port)<1024 ? isa_inw_p(port) : in_le16(port)) +#define inl(port) ((port)<1024 ? isa_inl(port) : in_le32(port)) +#define inl_p(port) ((port)<1024 ? isa_inl_p(port) : in_le32(port)) + +#define outb(val,port) ((port)<1024 ? isa_outb((val),(port)) : out_8((port),(val))) +#define outb_p(val,port) ((port)<1024 ? isa_outb_p((val),(port)) : out_8((port),(val))) +#define outw(val,port) ((port)<1024 ? isa_outw((val),(port)) : out_le16((port),(val))) +#define outw_p(val,port) ((port)<1024 ? isa_outw_p((val),(port)) : out_le16((port),(val))) +#define outl(val,port) ((port)<1024 ? isa_outl((val),(port)) : out_le32((port),(val))) +#define outl_p(val,port) ((port)<1024 ? isa_outl_p((val),(port)) : out_le32((port),(val))) +#endif +#endif /* CONFIG_PCI */ + +#if !defined(CONFIG_ISA) && !defined(CONFIG_PCI) && defined(CONFIG_HP300) +/* + * We need to define dummy functions otherwise drivers/serial/8250.c doesn't link + */ +#define inb(port) 0xff +#define inb_p(port) 0xff +#define outb(val,port) do { } while (0) +#define outb_p(val,port) do { } while (0) + +/* + * These should be valid on any ioremap()ed region + */ +#define readb(addr) in_8(addr) +#define writeb(val,addr) out_8((addr),(val)) +#define readl(addr) in_le32(addr) +#define writel(val,addr) out_le32((addr),(val)) +#endif + +#define mmiowb() + +static inline void *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +static inline void *ioremap_writethrough(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} +static inline void *ioremap_fullcache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + + +/* m68k caches aren't DMA coherent */ +extern void dma_cache_wback_inv(unsigned long start, unsigned long size); +extern void dma_cache_wback(unsigned long start, unsigned long size); +extern void dma_cache_inv(unsigned long start, unsigned long size); + + +#ifndef CONFIG_SUN3 +#define IO_SPACE_LIMIT 0xffff +#else +#define IO_SPACE_LIMIT 0x0fffffff +#endif + +#endif /* __KERNEL__ */ + +#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1 + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +#endif /* _IO_H */ diff --git a/include/asm-m68k/ioctl.h b/include/asm-m68k/ioctl.h new file mode 100644 index 000000000000..fd68914ab292 --- /dev/null +++ b/include/asm-m68k/ioctl.h @@ -0,0 +1,80 @@ +/* $Id: ioctl.h,v 1.3 1997/04/16 15:10:07 jes 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 000000000000..0c48929ab444 --- /dev/null +++ b/include/asm-m68k/ioctls.h @@ -0,0 +1,80 @@ +#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 TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#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 */ +#define FIOQSIZE 0x545E + +/* 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 000000000000..a46e3d9c2a3f --- /dev/null +++ b/include/asm-m68k/ipc.h @@ -0,0 +1 @@ +#include <asm-generic/ipc.h> diff --git a/include/asm-m68k/ipcbuf.h b/include/asm-m68k/ipcbuf.h new file mode 100644 index 000000000000..a623ea3f0955 --- /dev/null +++ b/include/asm-m68k/ipcbuf.h @@ -0,0 +1,29 @@ +#ifndef __m68k_IPCBUF_H__ +#define __m68k_IPCBUF_H__ + +/* + * The user_ipc_perm structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* __m68k_IPCBUF_H__ */ diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h new file mode 100644 index 000000000000..1f569905cb74 --- /dev/null +++ b/include/asm-m68k/irq.h @@ -0,0 +1,131 @@ +#ifndef _M68K_IRQ_H_ +#define _M68K_IRQ_H_ + +#include <linux/config.h> +#include <linux/interrupt.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) || defined(CONFIG_MAC) +#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 */ + +static __inline__ int irq_canonicalize(int irq) +{ + return irq; +} + +/* + * 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. + * + * The IRQ_MACHSPEC bit is now gone - the only thing it did was to + * introduce unnecessary overhead. + * + * All interrupt handling is actually machine specific so it is better + * to use function pointers, as used by the Sparc port, and select the + * interrupt handling functions when initializing the kernel. This way + * we save some unnecessary overhead at run-time. + * 01/11/97 - Jes + */ + +extern void (*enable_irq)(unsigned int); +extern void (*disable_irq)(unsigned int); + +#define disable_irq_nosync disable_irq +#define enable_irq_nosync enable_irq + +struct pt_regs; + +extern int cpu_request_irq(unsigned int, + irqreturn_t (*)(int, void *, struct pt_regs *), + unsigned long, const char *, void *); +extern void cpu_free_irq(unsigned int, void *); + +/* + * various flags for request_irq() - the Amiga now uses the standard + * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ + * are your friends. + */ +#ifndef MACH_AMIGA_ONLY +#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 */ +#endif + +/* + * This structure is used to chain together the ISRs for a particular + * interrupt source (if it supports chaining). + */ +typedef struct irq_node { + irqreturn_t (*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 { + irqreturn_t (*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); + +struct irqaction; +struct pt_regs; +int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); + +#endif /* _M68K_IRQ_H_ */ diff --git a/include/asm-m68k/kbio.h b/include/asm-m68k/kbio.h new file mode 100644 index 000000000000..e1fbf8fba3e8 --- /dev/null +++ b/include/asm-m68k/kbio.h @@ -0,0 +1 @@ +#include <asm-sparc/kbio.h> diff --git a/include/asm-m68k/kmap_types.h b/include/asm-m68k/kmap_types.h new file mode 100644 index 000000000000..c843c63d3801 --- /dev/null +++ b/include/asm-m68k/kmap_types.h @@ -0,0 +1,21 @@ +#ifndef __ASM_M68K_KMAP_TYPES_H +#define __ASM_M68K_KMAP_TYPES_H + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#endif /* __ASM_M68K_KMAP_TYPES_H */ diff --git a/include/asm-m68k/linkage.h b/include/asm-m68k/linkage.h new file mode 100644 index 000000000000..5a822bb790f7 --- /dev/null +++ b/include/asm-m68k/linkage.h @@ -0,0 +1,7 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#define __ALIGN .align 4 +#define __ALIGN_STR ".align 4" + +#endif diff --git a/include/asm-m68k/local.h b/include/asm-m68k/local.h new file mode 100644 index 000000000000..6c259263e1f0 --- /dev/null +++ b/include/asm-m68k/local.h @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_LOCAL_H +#define _ASM_M68K_LOCAL_H + +#include <asm-generic/local.h> + +#endif /* _ASM_M68K_LOCAL_H */ diff --git a/include/asm-m68k/mac_asc.h b/include/asm-m68k/mac_asc.h new file mode 100644 index 000000000000..fc2e5467b41e --- /dev/null +++ b/include/asm-m68k/mac_asc.h @@ -0,0 +1,27 @@ +/* + * Apple Sound Chip + */ + +#ifndef __ASM_MAC_ASC_H +#define __ASM_MAC_ASC_H + +/* + * ASC offsets and controls + */ + +#define ASC_BUF_BASE 0x00 /* RAM buffer offset */ +#define ASC_BUF_SIZE 0x800 + +#define ASC_CONTROL 0x800 +#define ASC_CONTROL_OFF 0x00 +#define ASC_FREQ(chan,byte) ((0x810)+((chan)<<3)+(byte)) +#define ASC_ENABLE 0x801 +#define ASC_ENABLE_SAMPLE 0x02 +#define ASC_MODE 0x802 +#define ASC_MODE_SAMPLE 0x02 + +#define ASC_VOLUME 0x806 +#define ASC_CHAN 0x807 /* ??? */ + + +#endif diff --git a/include/asm-m68k/mac_baboon.h b/include/asm-m68k/mac_baboon.h new file mode 100644 index 000000000000..e87850830be8 --- /dev/null +++ b/include/asm-m68k/mac_baboon.h @@ -0,0 +1,34 @@ +/* + * Definitions for the "Baboon" custom IC on the PowerBook 190. + */ + +#define BABOON_BASE (0x50F1A000) /* same as IDE controller base */ + +#ifndef __ASSEMBLY__ + +struct baboon { + char pad1[208]; /* generic IDE registers, not used here */ + short mb_control; /* Control register: + * bit 5 : slot 2 power control + * bit 6 : slot 1 power control + */ + char pad2[2]; + short mb_status; /* (0xD4) media bay status register: + * + * bit 0: ???? + * bit 1: IDE interrupt active? + * bit 2: bay status, 0 = full, 1 = empty + * bit 3: ???? + */ + char pad3[2]; /* (0xD6) not used */ + short mb_ifr; /* (0xD8) media bay interrupt flags register: + * + * bit 0: ???? + * bit 1: IDE controller interrupt + * bit 2: media bay status change interrupt + */ +}; + +extern volatile struct baboon *baboon; + +#endif /* __ASSEMBLY **/ diff --git a/include/asm-m68k/mac_iop.h b/include/asm-m68k/mac_iop.h new file mode 100644 index 000000000000..b0d2e3473537 --- /dev/null +++ b/include/asm-m68k/mac_iop.h @@ -0,0 +1,162 @@ +/* + * I/O Processor (IOP) defines and structures, mostly snagged from A/UX + * header files. + * + * The original header from which this was taken is copyrighted. I've done some + * rewriting (in fact my changes make this a bit more readable, IMHO) but some + * more should be done. + */ + +/* + * This is the base address of the IOPs. Use this as the address of + * a "struct iop" (see below) to see where the actual registers fall. + */ + +#define SCC_IOP_BASE_IIFX (0x50F04000) +#define ISM_IOP_BASE_IIFX (0x50F12000) + +#define SCC_IOP_BASE_QUADRA (0x50F0C000) +#define ISM_IOP_BASE_QUADRA (0x50F1E000) + +/* IOP status/control register bits: */ + +#define IOP_BYPASS 0x01 /* bypass-mode hardware access */ +#define IOP_AUTOINC 0x02 /* allow autoincrement of ramhi/lo */ +#define IOP_RUN 0x04 /* set to 0 to reset IOP chip */ +#define IOP_IRQ 0x08 /* generate IRQ to IOP if 1 */ +#define IOP_INT0 0x10 /* intr priority from IOP to host */ +#define IOP_INT1 0x20 /* intr priority from IOP to host */ +#define IOP_HWINT 0x40 /* IRQ from hardware; bypass mode only */ +#define IOP_DMAINACTIVE 0x80 /* no DMA request active; bypass mode only */ + +#define NUM_IOPS 2 +#define NUM_IOP_CHAN 7 +#define NUM_IOP_MSGS NUM_IOP_CHAN*8 +#define IOP_MSG_LEN 32 + +/* IOP reference numbers, used by the globally-visible iop_xxx functions */ + +#define IOP_NUM_SCC 0 +#define IOP_NUM_ISM 1 + +/* IOP channel states */ + +#define IOP_MSG_IDLE 0 /* idle */ +#define IOP_MSG_NEW 1 /* new message sent */ +#define IOP_MSG_RCVD 2 /* message received; processing */ +#define IOP_MSG_COMPLETE 3 /* message processing complete */ + +/* IOP message status codes */ + +#define IOP_MSGSTATUS_UNUSED 0 /* Unusued message structure */ +#define IOP_MSGSTATUS_WAITING 1 /* waiting for channel */ +#define IOP_MSGSTATUS_SENT 2 /* message sent, awaiting reply */ +#define IOP_MSGSTATUS_COMPLETE 3 /* message complete and reply rcvd */ +#define IOP_MSGSTATUS_UNSOL 6 /* message is unsolicited */ + +/* IOP memory addresses of the members of the mac_iop_kernel structure. */ + +#define IOP_ADDR_MAX_SEND_CHAN 0x0200 +#define IOP_ADDR_SEND_STATE 0x0201 +#define IOP_ADDR_PATCH_CTRL 0x021F +#define IOP_ADDR_SEND_MSG 0x0220 +#define IOP_ADDR_MAX_RECV_CHAN 0x0300 +#define IOP_ADDR_RECV_STATE 0x0301 +#define IOP_ADDR_ALIVE 0x031F +#define IOP_ADDR_RECV_MSG 0x0320 + +#ifndef __ASSEMBLY__ + +/* + * IOP Control registers, staggered because in usual Apple style they were + * too lazy to decode the A0 bit. This structure is assumed to begin at + * one of the xxx_IOP_BASE addresses given above. + */ + +struct mac_iop { + __u8 ram_addr_hi; /* shared RAM address hi byte */ + __u8 pad0; + __u8 ram_addr_lo; /* shared RAM address lo byte */ + __u8 pad1; + __u8 status_ctrl; /* status/control register */ + __u8 pad2[3]; + __u8 ram_data; /* RAM data byte at ramhi/lo */ + + __u8 pad3[23]; + + /* Bypass-mode hardware access registers */ + + union { + struct { /* SCC registers */ + __u8 sccb_cmd; /* SCC B command reg */ + __u8 pad4; + __u8 scca_cmd; /* SCC A command reg */ + __u8 pad5; + __u8 sccb_data; /* SCC B data */ + __u8 pad6; + __u8 scca_data; /* SCC A data */ + } scc_regs; + + struct { /* ISM registers */ + __u8 wdata; /* write a data byte */ + __u8 pad7; + __u8 wmark; /* write a mark byte */ + __u8 pad8; + __u8 wcrc; /* write 2-byte crc to disk */ + __u8 pad9; + __u8 wparams; /* write the param regs */ + __u8 pad10; + __u8 wphase; /* write the phase states & dirs */ + __u8 pad11; + __u8 wsetup; /* write the setup register */ + __u8 pad12; + __u8 wzeroes; /* mode reg: 1's clr bits, 0's are x */ + __u8 pad13; + __u8 wones; /* mode reg: 1's set bits, 0's are x */ + __u8 pad14; + __u8 rdata; /* read a data byte */ + __u8 pad15; + __u8 rmark; /* read a mark byte */ + __u8 pad16; + __u8 rerror; /* read the error register */ + __u8 pad17; + __u8 rparams; /* read the param regs */ + __u8 pad18; + __u8 rphase; /* read the phase states & dirs */ + __u8 pad19; + __u8 rsetup; /* read the setup register */ + __u8 pad20; + __u8 rmode; /* read the mode register */ + __u8 pad21; + __u8 rhandshake; /* read the handshake register */ + } ism_regs; + } b; +}; + +/* This structure is used to track IOP messages in the Linux kernel */ + +struct iop_msg { + struct iop_msg *next; /* next message in queue or NULL */ + uint iop_num; /* IOP number */ + uint channel; /* channel number */ + void *caller_priv; /* caller private data */ + int status; /* status of this message */ + __u8 message[IOP_MSG_LEN]; /* the message being sent/received */ + __u8 reply[IOP_MSG_LEN]; /* the reply to the message */ + void (*handler)(struct iop_msg *, struct pt_regs *); + /* function to call when reply recvd */ +}; + +extern int iop_scc_present,iop_ism_present; + +extern int iop_listen(uint, uint, + void (*handler)(struct iop_msg *, struct pt_regs *), + const char *); +extern int iop_send_message(uint, uint, void *, uint, __u8 *, + void (*)(struct iop_msg *, struct pt_regs *)); +extern void iop_complete_message(struct iop_msg *); +extern void iop_upload_code(uint, __u8 *, uint, __u16); +extern void iop_download_code(uint, __u8 *, uint, __u16); +extern __u8 *iop_compare_code(uint, __u8 *, uint, __u16); + +#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/mac_mouse.h b/include/asm-m68k/mac_mouse.h new file mode 100644 index 000000000000..39a5c292eaee --- /dev/null +++ b/include/asm-m68k/mac_mouse.h @@ -0,0 +1,23 @@ +#ifndef _ASM_MAC_MOUSE_H +#define _ASM_MAC_MOUSE_H + +/* + * linux/include/asm-m68k/mac_mouse.h + * header file for Macintosh ADB mouse driver + * 27-10-97 Michael Schmitz + * copied from: + * 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; + wait_queue_head_t wait; + struct fasync_struct *fasyncptr; +}; + +#endif diff --git a/include/asm-m68k/mac_oss.h b/include/asm-m68k/mac_oss.h new file mode 100644 index 000000000000..7644a639cd6c --- /dev/null +++ b/include/asm-m68k/mac_oss.h @@ -0,0 +1,94 @@ +/* + * OSS + * + * This is used in place of VIA2 on the IIfx. + */ + +#define OSS_BASE (0x50f1a000) + +/* + * Interrupt level offsets for mac_oss->irq_level + */ + +#define OSS_NUBUS0 0 +#define OSS_NUBUS1 1 +#define OSS_NUBUS2 2 +#define OSS_NUBUS3 3 +#define OSS_NUBUS4 4 +#define OSS_NUBUS5 5 +#define OSS_IOPISM 6 +#define OSS_IOPSCC 7 +#define OSS_SOUND 8 +#define OSS_SCSI 9 +#define OSS_60HZ 10 +#define OSS_VIA1 11 +#define OSS_UNUSED1 12 +#define OSS_UNUSED2 13 +#define OSS_PARITY 14 +#define OSS_UNUSED3 15 + +#define OSS_NUM_SOURCES 16 + +/* + * Pending interrupt bits in mac_oss->irq_pending + */ + +#define OSS_IP_NUBUS0 0x0001 +#define OSS_IP_NUBUS1 0x0002 +#define OSS_IP_NUBUS2 0x0004 +#define OSS_IP_NUBUS3 0x0008 +#define OSS_IP_NUBUS4 0x0010 +#define OSS_IP_NUBUS5 0x0020 +#define OSS_IP_IOPISM 0x0040 +#define OSS_IP_IOPSCC 0x0080 +#define OSS_IP_SOUND 0x0100 +#define OSS_IP_SCSI 0x0200 +#define OSS_IP_60HZ 0x0400 +#define OSS_IP_VIA1 0x0800 +#define OSS_IP_UNUSED1 0x1000 +#define OSS_IP_UNUSED2 0x2000 +#define OSS_IP_PARITY 0x4000 +#define OSS_IP_UNUSED3 0x8000 + +#define OSS_IP_NUBUS (OSS_IP_NUBUS0|OSS_IP_NUBUS1|OSS_IP_NUBUS2|OSS_IP_NUBUS3|OSS_IP_NUBUS4|OSS_IP_NUBUS5) + +/* + * Rom Control Register + */ + +#define OSS_POWEROFF 0x80 + +/* + * OSS Interrupt levels for various sub-systems + * + * This mapping is layed out with two things in mind: first, we try to keep + * things on their own levels to avoid having to do double-dispatches. Second, + * the levels match as closely as possible the alternate IRQ mapping mode (aka + * "A/UX mode") available on some VIA machines. + */ + +#define OSS_IRQLEV_DISABLED 0 +#define OSS_IRQLEV_IOPISM 1 /* ADB? */ +#define OSS_IRQLEV_SCSI 2 +#define OSS_IRQLEV_NUBUS 3 /* keep this on its own level */ +#define OSS_IRQLEV_IOPSCC 4 /* matches VIA alternate mapping */ +#define OSS_IRQLEV_SOUND 5 /* matches VIA alternate mapping */ +#define OSS_IRQLEV_60HZ 6 /* matches VIA alternate mapping */ +#define OSS_IRQLEV_VIA1 6 /* matches VIA alternate mapping */ +#define OSS_IRQLEV_PARITY 7 /* matches VIA alternate mapping */ + +#ifndef __ASSEMBLY__ + +struct mac_oss { + __u8 irq_level[0x10]; /* [0x000-0x00f] Interrupt levels */ + __u8 padding0[0x1F2]; /* [0x010-0x201] IO space filler */ + __u16 irq_pending; /* [0x202-0x203] pending interrupts bits */ + __u8 rom_ctrl; /* [0x204-0x204] ROM cntl reg (for poweroff) */ + __u8 padding1[0x2]; /* [0x205-0x206] currently unused by A/UX */ + __u8 ack_60hz; /* [0x207-0x207] 60 Hz ack. */ +}; + +extern volatile struct mac_oss *oss; +extern int oss_present; + +#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/mac_psc.h b/include/asm-m68k/mac_psc.h new file mode 100644 index 000000000000..7808bb0b2323 --- /dev/null +++ b/include/asm-m68k/mac_psc.h @@ -0,0 +1,248 @@ +/* + * Apple Peripheral System Controller (PSC) + * + * The PSC is used on the AV Macs to control IO functions not handled + * by the VIAs (Ethernet, DSP, SCC, Sound). This includes nine DMA + * channels. + * + * The first seven DMA channels appear to be "one-shot" and are actually + * sets of two channels; one member is active while the other is being + * configured, and then you flip the active member and start all over again. + * The one-shot channels are grouped together and are: + * + * 1. SCSI + * 2. Ethernet Read + * 3. Ethernet Write + * 4. Floppy Disk Controller + * 5. SCC Channel A Receive + * 6. SCC Channel B Receive + * 7. SCC Channel A Transmit + * + * The remaining two channels are handled somewhat differently. They appear + * to be closely tied and share one set of registers. They also seem to run + * continuously, although how you keep the buffer filled in this scenario is + * not understood as there seems to be only one input and one output buffer + * pointer. + * + * Much of this was extrapolated from what was known about the Ethernet + * registers and subsequently confirmed using MacsBug (ie by pinging the + * machine with easy-to-find patterns and looking for them in the DMA + * buffers, or by sending a file over the serial ports and finding the + * file in the buffers.) + * + * 1999-05-25 (jmt) + */ + +#define PSC_BASE (0x50F31000) + +/* + * The IER/IFR registers work like the VIA, except that it has 4 + * of them each on different interrupt levels, and each register + * set only seems to handle four interrupts instead of seven. + * + * To access a particular set of registers, add 0xn0 to the base + * where n = 3,4,5 or 6. + */ + +#define pIFRbase 0x100 +#define pIERbase 0x104 + +/* + * One-shot DMA control registers + */ + +#define PSC_MYSTERY 0x804 + +#define PSC_CTL_BASE 0xC00 + +#define PSC_SCSI_CTL 0xC00 +#define PSC_ENETRD_CTL 0xC10 +#define PSC_ENETWR_CTL 0xC20 +#define PSC_FDC_CTL 0xC30 +#define PSC_SCCA_CTL 0xC40 +#define PSC_SCCB_CTL 0xC50 +#define PSC_SCCATX_CTL 0xC60 + +/* + * DMA channels. Add +0x10 for the second channel in the set. + * You're supposed to use one channel while the other runs and + * then flip channels and do the whole thing again. + */ + +#define PSC_ADDR_BASE 0x1000 +#define PSC_LEN_BASE 0x1004 +#define PSC_CMD_BASE 0x1008 + +#define PSC_SET0 0x00 +#define PSC_SET1 0x10 + +#define PSC_SCSI_ADDR 0x1000 /* confirmed */ +#define PSC_SCSI_LEN 0x1004 /* confirmed */ +#define PSC_SCSI_CMD 0x1008 /* confirmed */ +#define PSC_ENETRD_ADDR 0x1020 /* confirmed */ +#define PSC_ENETRD_LEN 0x1024 /* confirmed */ +#define PSC_ENETRD_CMD 0x1028 /* confirmed */ +#define PSC_ENETWR_ADDR 0x1040 /* confirmed */ +#define PSC_ENETWR_LEN 0x1044 /* confirmed */ +#define PSC_ENETWR_CMD 0x1048 /* confirmed */ +#define PSC_FDC_ADDR 0x1060 /* strongly suspected */ +#define PSC_FDC_LEN 0x1064 /* strongly suspected */ +#define PSC_FDC_CMD 0x1068 /* strongly suspected */ +#define PSC_SCCA_ADDR 0x1080 /* confirmed */ +#define PSC_SCCA_LEN 0x1084 /* confirmed */ +#define PSC_SCCA_CMD 0x1088 /* confirmed */ +#define PSC_SCCB_ADDR 0x10A0 /* confirmed */ +#define PSC_SCCB_LEN 0x10A4 /* confirmed */ +#define PSC_SCCB_CMD 0x10A8 /* confirmed */ +#define PSC_SCCATX_ADDR 0x10C0 /* confirmed */ +#define PSC_SCCATX_LEN 0x10C4 /* confirmed */ +#define PSC_SCCATX_CMD 0x10C8 /* confirmed */ + +/* + * Free-running DMA registers. The only part known for sure are the bits in + * the control register, the buffer addresses and the buffer length. Everything + * else is anybody's guess. + * + * These registers seem to be mirrored every thirty-two bytes up until offset + * 0x300. It's safe to assume then that a new set of registers starts there. + */ + +#define PSC_SND_CTL 0x200 /* + * [ 16-bit ] + * Sound (Singer?) control register. + * + * bit 0 : ???? + * bit 1 : ???? + * bit 2 : Set to one to enable sound + * output. Possibly a mute flag. + * bit 3 : ???? + * bit 4 : ???? + * bit 5 : ???? + * bit 6 : Set to one to enable pass-thru + * audio. In this mode the audio data + * seems to appear in both the input + * buffer and the output buffer. + * bit 7 : Set to one to activate the + * sound input DMA or zero to + * disable it. + * bit 8 : Set to one to activate the + * sound output DMA or zero to + * disable it. + * bit 9 : \ + * bit 11 : | + * These two bits control the sample + * rate. Usually set to binary 10 and + * MacOS 8.0 says I'm at 48 KHz. Using + * a binary value of 01 makes things + * sound about 1/2 speed (24 KHz?) and + * binary 00 is slower still (22 KHz?) + * + * Setting this to 0x0000 is a good way to + * kill all DMA at boot time so that the + * PSC won't overwrite the kernel image + * with sound data. + */ + +/* + * 0x0202 - 0x0203 is unused. Writing there + * seems to clobber the control register. + */ + +#define PSC_SND_SOURCE 0x204 /* + * [ 32-bit ] + * Controls input source and volume: + * + * bits 12-15 : input source volume, 0 - F + * bits 16-19 : unknown, always 0x5 + * bits 20-23 : input source selection: + * 0x3 = CD Audio + * 0x4 = External Audio + * + * The volume is definitely not the general + * output volume as it doesn't affect the + * alert sound volume. + */ +#define PSC_SND_STATUS1 0x208 /* + * [ 32-bit ] + * Appears to be a read-only status register. + * The usual value is 0x00400002. + */ +#define PSC_SND_HUH3 0x20C /* + * [ 16-bit ] + * Unknown 16-bit value, always 0x0000. + */ +#define PSC_SND_BITS2GO 0x20E /* + * [ 16-bit ] + * Counts down to zero from some constant + * value. The value appears to be the + * number of _bits_ remaining before the + * buffer is full, which would make sense + * since Apple's docs say the sound DMA + * channels are 1 bit wide. + */ +#define PSC_SND_INADDR 0x210 /* + * [ 32-bit ] + * Address of the sound input DMA buffer + */ +#define PSC_SND_OUTADDR 0x214 /* + * [ 32-bit ] + * Address of the sound output DMA buffer + */ +#define PSC_SND_LEN 0x218 /* + * [ 16-bit ] + * Length of both buffers in eight-byte units. + */ +#define PSC_SND_HUH4 0x21A /* + * [ 16-bit ] + * Unknown, always 0x0000. + */ +#define PSC_SND_STATUS2 0x21C /* + * [ 16-bit ] + * Appears to e a read-only status register. + * The usual value is 0x0200. + */ +#define PSC_SND_HUH5 0x21E /* + * [ 16-bit ] + * Unknown, always 0x0000. + */ + +#ifndef __ASSEMBLY__ + +extern volatile __u8 *psc; +extern int psc_present; + +/* + * Access functions + */ + +static inline void psc_write_byte(int offset, __u8 data) +{ + *((volatile __u8 *)(psc + offset)) = data; +} + +static inline void psc_write_word(int offset, __u16 data) +{ + *((volatile __u16 *)(psc + offset)) = data; +} + +static inline void psc_write_long(int offset, __u32 data) +{ + *((volatile __u32 *)(psc + offset)) = data; +} + +static inline u8 psc_read_byte(int offset) +{ + return *((volatile __u8 *)(psc + offset)); +} + +static inline u16 psc_read_word(int offset) +{ + return *((volatile __u16 *)(psc + offset)); +} + +static inline u32 psc_read_long(int offset) +{ + return *((volatile __u32 *)(psc + offset)); +} + +#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/mac_via.h b/include/asm-m68k/mac_via.h new file mode 100644 index 000000000000..59b758cd16ad --- /dev/null +++ b/include/asm-m68k/mac_via.h @@ -0,0 +1,268 @@ +/* + * 6522 Versatile Interface Adapter (VIA) + * + * There are two of these on the Mac II. Some IRQ's are vectored + * via them as are assorted bits and bobs - eg rtc, adb. The picture + * is a bit incomplete as the Mac documentation doesn't cover this well + */ + +#ifndef _ASM_MAC_VIA_H_ +#define _ASM_MAC_VIA_H_ + +/* + * Base addresses for the VIAs. There are two in every machine, + * although on some machines the second is an RBV or an OSS. + * The OSS is different enough that it's handled separately. + * + * Do not use these values directly; use the via1 and via2 variables + * instead (and don't forget to check rbv_present when using via2!) + */ + +#define VIA1_BASE (0x50F00000) +#define VIA2_BASE (0x50F02000) +#define RBV_BASE (0x50F26000) + +/* + * Not all of these are true post MacII I think. + * CSA: probably the ones CHRP marks as 'unused' change purposes + * when the IWM becomes the SWIM. + * http://www.rs6000.ibm.com/resource/technology/chrpio/via5.mak.html + * ftp://ftp.austin.ibm.com/pub/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf + * + * also, http://developer.apple.com/technotes/hw/hw_09.html claims the + * following changes for IIfx: + * VIA1A_vSccWrReq not available and that VIA1A_vSync has moved to an IOP. + * Also, "All of the functionality of VIA2 has been moved to other chips". + */ + +#define VIA1A_vSccWrReq 0x80 /* SCC write. (input) + * [CHRP] SCC WREQ: Reflects the state of the + * Wait/Request pins from the SCC. + * [Macintosh Family Hardware] + * as CHRP on SE/30,II,IIx,IIcx,IIci. + * on IIfx, "0 means an active request" + */ +#define VIA1A_vRev8 0x40 /* Revision 8 board ??? + * [CHRP] En WaitReqB: Lets the WaitReq_L + * signal from port B of the SCC appear on + * the PA7 input pin. Output. + * [Macintosh Family] On the SE/30, this + * is the bit to flip screen buffers. + * 0=alternate, 1=main. + * on II,IIx,IIcx,IIci,IIfx this is a bit + * for Rev ID. 0=II,IIx, 1=IIcx,IIci,IIfx + */ +#define VIA1A_vHeadSel 0x20 /* Head select for IWM. + * [CHRP] unused. + * [Macintosh Family] "Floppy disk + * state-control line SEL" on all but IIfx + */ +#define VIA1A_vOverlay 0x10 /* [Macintosh Family] On SE/30,II,IIx,IIcx + * this bit enables the "Overlay" address + * map in the address decoders as it is on + * reset for mapping the ROM over the reset + * vector. 1=use overlay map. + * On the IIci,IIfx it is another bit of the + * CPU ID: 0=normal IIci, 1=IIci with parity + * feature or IIfx. + * [CHRP] En WaitReqA: Lets the WaitReq_L + * signal from port A of the SCC appear + * on the PA7 input pin (CHRP). Output. + * [MkLinux] "Drive Select" + * (with 0x20 being 'disk head select') + */ +#define VIA1A_vSync 0x08 /* [CHRP] Sync Modem: modem clock select: + * 1: select the external serial clock to + * drive the SCC's /RTxCA pin. + * 0: Select the 3.6864MHz clock to drive + * the SCC cell. + * [Macintosh Family] Correct on all but IIfx + */ + +/* Macintosh Family Hardware sez: bits 0-2 of VIA1A are volume control + * on Macs which had the PWM sound hardware. Reserved on newer models. + * On IIci,IIfx, bits 1-2 are the rest of the CPU ID: + * bit 2: 1=IIci, 0=IIfx + * bit 1: 1 on both IIci and IIfx. + * MkLinux sez bit 0 is 'burnin flag' in this case. + * CHRP sez: VIA1A bits 0-2 and 5 are 'unused': if programmed as + * inputs, these bits will read 0. + */ +#define VIA1A_vVolume 0x07 /* Audio volume mask for PWM */ +#define VIA1A_CPUID0 0x02 /* CPU id bit 0 on RBV, others */ +#define VIA1A_CPUID1 0x04 /* CPU id bit 0 on RBV, others */ +#define VIA1A_CPUID2 0x10 /* CPU id bit 0 on RBV, others */ +#define VIA1A_CPUID3 0x40 /* CPU id bit 0 on RBV, others */ + +/* Info on VIA1B is from Macintosh Family Hardware & MkLinux. + * CHRP offers no info. */ +#define VIA1B_vSound 0x80 /* Sound enable (for compatibility with + * PWM hardware) 0=enabled. + * Also, on IIci w/parity, shows parity error + * 0=error, 1=OK. */ +#define VIA1B_vMystery 0x40 /* On IIci, parity enable. 0=enabled,1=disabled + * On SE/30, vertical sync interrupt enable. + * 0=enabled. This vSync interrupt shows up + * as a slot $E interrupt. */ +#define VIA1B_vADBS2 0x20 /* ADB state input bit 1 (unused on IIfx) */ +#define VIA1B_vADBS1 0x10 /* ADB state input bit 0 (unused on IIfx) */ +#define VIA1B_vADBInt 0x08 /* ADB interrupt 0=interrupt (unused on IIfx)*/ +#define VIA1B_vRTCEnb 0x04 /* Enable Real time clock. 0=enabled. */ +#define VIA1B_vRTCClk 0x02 /* Real time clock serial-clock line. */ +#define VIA1B_vRTCData 0x01 /* Real time clock serial-data line. */ + +/* MkLinux defines the following "VIA1 Register B contents where they + * differ from standard VIA1". From the naming scheme, we assume they + * correspond to a VIA work-alike named 'EVR'. */ +#define EVRB_XCVR 0x08 /* XCVR_SESSION* */ +#define EVRB_FULL 0x10 /* VIA_FULL */ +#define EVRB_SYSES 0x20 /* SYS_SESSION */ +#define EVRB_AUXIE 0x00 /* Enable A/UX Interrupt Scheme */ +#define EVRB_AUXID 0x40 /* Disable A/UX Interrupt Scheme */ +#define EVRB_SFTWRIE 0x00 /* Software Interrupt ReQuest */ +#define EVRB_SFTWRID 0x80 /* Software Interrupt ReQuest */ + +/* + * VIA2 A register is the interrupt lines raised off the nubus + * slots. + * The below info is from 'Macintosh Family Hardware.' + * MkLinux calls the 'IIci internal video IRQ' below the 'RBV slot 0 irq.' + * It also notes that the slot $9 IRQ is the 'Ethernet IRQ' and + * defines the 'Video IRQ' as 0x40 for the 'EVR' VIA work-alike. + * Perhaps OSS uses vRAM1 and vRAM2 for ADB. + */ + +#define VIA2A_vRAM1 0x80 /* RAM size bit 1 (IIci: reserved) */ +#define VIA2A_vRAM0 0x40 /* RAM size bit 0 (IIci: internal video IRQ) */ +#define VIA2A_vIRQE 0x20 /* IRQ from slot $E */ +#define VIA2A_vIRQD 0x10 /* IRQ from slot $D */ +#define VIA2A_vIRQC 0x08 /* IRQ from slot $C */ +#define VIA2A_vIRQB 0x04 /* IRQ from slot $B */ +#define VIA2A_vIRQA 0x02 /* IRQ from slot $A */ +#define VIA2A_vIRQ9 0x01 /* IRQ from slot $9 */ + +/* RAM size bits decoded as follows: + * bit1 bit0 size of ICs in bank A + * 0 0 256 kbit + * 0 1 1 Mbit + * 1 0 4 Mbit + * 1 1 16 Mbit + */ + +/* + * Register B has the fun stuff in it + */ + +#define VIA2B_vVBL 0x80 /* VBL output to VIA1 (60.15Hz) driven by + * timer T1. + * on IIci, parity test: 0=test mode. + * [MkLinux] RBV_PARODD: 1=odd,0=even. */ +#define VIA2B_vSndJck 0x40 /* External sound jack status. + * 0=plug is inserted. On SE/30, always 0 */ +#define VIA2B_vTfr0 0x20 /* Transfer mode bit 0 ack from NuBus */ +#define VIA2B_vTfr1 0x10 /* Transfer mode bit 1 ack from NuBus */ +#define VIA2B_vMode32 0x08 /* 24/32bit switch - doubles as cache flush + * on II, AMU/PMMU control. + * if AMU, 0=24bit to 32bit translation + * if PMMU, 1=PMMU is accessing page table. + * on SE/30 tied low. + * on IIx,IIcx,IIfx, unused. + * on IIci/RBV, cache control. 0=flush cache. + */ +#define VIA2B_vPower 0x04 /* Power off, 0=shut off power. + * on SE/30 this signal sent to PDS card. */ +#define VIA2B_vBusLk 0x02 /* Lock NuBus transactions, 0=locked. + * on SE/30 sent to PDS card. */ +#define VIA2B_vCDis 0x01 /* Cache control. On IIci, 1=disable cache card + * on others, 0=disable processor's instruction + * and data caches. */ + +/* Apple sez: http://developer.apple.com/technotes/ov/ov_04.html + * Another example of a valid function that has no ROM support is the use + * of the alternate video page for page-flipping animation. Since there + * is no ROM call to flip pages, it is necessary to go play with the + * right bit in the VIA chip (6522 Versatile Interface Adapter). + * [CSA: don't know which one this is, but it's one of 'em!] + */ + +/* + * 6522 registers - see databook. + * CSA: Assignments for VIA1 confirmed from CHRP spec. + */ + +/* partial address decode. 0xYYXX : XX part for RBV, YY part for VIA */ +/* Note: 15 VIA regs, 8 RBV regs */ + +#define vBufB 0x0000 /* [VIA/RBV] Register B */ +#define vBufAH 0x0200 /* [VIA only] Buffer A, with handshake. DON'T USE! */ +#define vDirB 0x0400 /* [VIA only] Data Direction Register B. */ +#define vDirA 0x0600 /* [VIA only] Data Direction Register A. */ +#define vT1CL 0x0800 /* [VIA only] Timer one counter low. */ +#define vT1CH 0x0a00 /* [VIA only] Timer one counter high. */ +#define vT1LL 0x0c00 /* [VIA only] Timer one latches low. */ +#define vT1LH 0x0e00 /* [VIA only] Timer one latches high. */ +#define vT2CL 0x1000 /* [VIA only] Timer two counter low. */ +#define vT2CH 0x1200 /* [VIA only] Timer two counter high. */ +#define vSR 0x1400 /* [VIA only] Shift register. */ +#define vACR 0x1600 /* [VIA only] Auxilary control register. */ +#define vPCR 0x1800 /* [VIA only] Peripheral control register. */ + /* CHRP sez never ever to *write* this. + * Mac family says never to *change* this. + * In fact we need to initialize it once at start. */ +#define vIFR 0x1a00 /* [VIA/RBV] Interrupt flag register. */ +#define vIER 0x1c00 /* [VIA/RBV] Interrupt enable register. */ +#define vBufA 0x1e00 /* [VIA/RBV] register A (no handshake) */ + +/* The RBV only decodes the bottom eight address lines; the VIA doesn't + * decode the bottom eight -- so vBufB | rBufB will always get you BufB */ +/* CSA: in fact, only bits 0,1, and 4 seem to be decoded. + * BUT note the values for rIER and rIFR, where the top 8 bits *do* seem + * to matter. In fact *all* of the top 8 bits seem to matter; + * setting rIER=0x1813 and rIFR=0x1803 doesn't work, either. + * Perhaps some sort of 'compatibility mode' is built-in? [21-May-1999] + */ + +#define rBufB 0x0000 /* [VIA/RBV] Register B */ +#define rExp 0x0001 /* [RBV only] RBV future expansion (always 0) */ +#define rSIFR 0x0002 /* [RBV only] RBV slot interrupts register. */ +#define rIFR 0x1a03 /* [VIA/RBV] RBV interrupt flag register. */ +#define rMonP 0x0010 /* [RBV only] RBV video monitor type. */ +#define rChpT 0x0011 /* [RBV only] RBV test mode register (reads as 0). */ +#define rSIER 0x0012 /* [RBV only] RBV slot interrupt enables. */ +#define rIER 0x1c13 /* [VIA/RBV] RBV interrupt flag enable register. */ +#define rBufA rSIFR /* the 'slot interrupts register' is BufA on a VIA */ + +/* + * Video monitor parameters, for rMonP: + */ +#define RBV_DEPTH 0x07 /* bits per pixel: 000=1,001=2,010=4,011=8 */ +#define RBV_MONID 0x38 /* monitor type, as below. */ +#define RBV_VIDOFF 0x40 /* 1 turns off onboard video */ +/* Supported monitor types: */ +#define MON_15BW (1<<3) /* 15" BW portrait. */ +#define MON_IIGS (2<<3) /* 12" color (modified IIGS monitor). */ +#define MON_15RGB (5<<3) /* 15" RGB portrait. */ +#define MON_12OR13 (6<<3) /* 12" BW or 13" RGB. */ +#define MON_NONE (7<<3) /* No monitor attached. */ + +/* To clarify IER manipulations */ +#define IER_SET_BIT(b) (0x80 | (1<<(b)) ) +#define IER_CLR_BIT(b) (0x7F & (1<<(b)) ) + +#ifndef __ASSEMBLY__ + +extern volatile __u8 *via1,*via2; +extern int rbv_present,via_alt_mapping; +extern __u8 rbv_clear; + +static inline int rbv_set_video_bpp(int bpp) +{ + char val = (bpp==1)?0:(bpp==2)?1:(bpp==4)?2:(bpp==8)?3:-1; + if (!rbv_present || val<0) return -1; + via2[rMonP] = (via2[rMonP] & ~RBV_DEPTH) | val; + return 0; +} + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_MAC_VIA_H_ */ diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h new file mode 100644 index 000000000000..a0dd5c47002c --- /dev/null +++ b/include/asm-m68k/machdep.h @@ -0,0 +1,42 @@ +#ifndef _M68K_MACHDEP_H +#define _M68K_MACHDEP_H + +#include <linux/seq_file.h> +#include <linux/interrupt.h> + +struct pt_regs; +struct mktime; +struct rtc_time; +struct rtc_pll_info; +struct buffer_head; + +extern void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)); +/* machine dependent irq functions */ +extern void (*mach_init_IRQ) (void); +extern irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); +extern int (*mach_request_irq) (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id); +extern void (*mach_free_irq) (unsigned int irq, void *dev_id); +extern void (*mach_get_model) (char *model); +extern int (*mach_get_hardware_list) (char *buffer); +extern int (*mach_get_irq_list) (struct seq_file *p, void *v); +extern irqreturn_t (*mach_process_int) (int irq, struct pt_regs *fp); +/* machine dependent timer functions */ +extern unsigned long (*mach_gettimeoffset)(void); +extern int (*mach_hwclk)(int, struct rtc_time*); +extern unsigned int (*mach_get_ss)(void); +extern int (*mach_get_rtc_pll)(struct rtc_pll_info *); +extern int (*mach_set_rtc_pll)(struct rtc_pll_info *); +extern int (*mach_set_clock_mmss)(unsigned long); +extern void (*mach_reset)( void ); +extern void (*mach_halt)( void ); +extern void (*mach_power_off)( void ); +extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); +extern void (*mach_hd_setup)(char *, int *); +extern long mach_max_dma_address; +extern void (*mach_floppy_setup)(char *, int *); +extern void (*mach_heartbeat) (int); +extern void (*mach_l2_flush) (int); +extern void (*mach_beep) (unsigned int, unsigned int); + +#endif /* _M68K_MACHDEP_H */ diff --git a/include/asm-m68k/machines.h b/include/asm-m68k/machines.h new file mode 100644 index 000000000000..da6015a90f24 --- /dev/null +++ b/include/asm-m68k/machines.h @@ -0,0 +1,87 @@ +/* $Id: machines.h,v 1.4 1995/11/25 02:31:58 davem Exp $ + * machines.h: Defines for taking apart the machine type value in the + * idprom and determining the kind of machine we are on. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Sun3/3x models added by David Monro (davidm@psrg.cs.usyd.edu.au) + */ +#ifndef _SPARC_MACHINES_H +#define _SPARC_MACHINES_H + +struct Sun_Machine_Models { + char *name; + unsigned char id_machtype; +}; + +/* Current number of machines we know about that has an IDPROM + * machtype entry including one entry for the 0x80 OBP machines. + */ +// reduced along with table in arch/m68k/sun3/idprom.c +// sun3 port doesn't need to know about sparc machines. +//#define NUM_SUN_MACHINES 23 +#define NUM_SUN_MACHINES 8 + +extern struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES]; + +/* The machine type in the idprom area looks like this: + * + * --------------- + * | ARCH | MACH | + * --------------- + * 7 4 3 0 + * + * The ARCH field determines the architecture line (sun4, sun4c, etc). + * The MACH field determines the machine make within that architecture. + */ + +#define SM_ARCH_MASK 0xf0 +#define SM_SUN3 0x10 +#define SM_SUN4 0x20 +#define SM_SUN3X 0x40 +#define SM_SUN4C 0x50 +#define SM_SUN4M 0x70 +#define SM_SUN4M_OBP 0x80 + +#define SM_TYP_MASK 0x0f +/* Sun3 machines */ +#define SM_3_160 0x01 /* Sun 3/160 series */ +#define SM_3_50 0x02 /* Sun 3/50 series */ +#define SM_3_260 0x03 /* Sun 3/260 series */ +#define SM_3_110 0x04 /* Sun 3/110 series */ +#define SM_3_60 0x07 /* Sun 3/60 series */ +#define SM_3_E 0x08 /* Sun 3/E series */ + +/* Sun3x machines */ +#define SM_3_460 0x01 /* Sun 3/460 (460,470,480) series */ +#define SM_3_80 0x02 /* Sun 3/80 series */ + +/* Sun4 machines */ +#define SM_4_260 0x01 /* Sun 4/200 series */ +#define SM_4_110 0x02 /* Sun 4/100 series */ +#define SM_4_330 0x03 /* Sun 4/300 series */ +#define SM_4_470 0x04 /* Sun 4/400 series */ + +/* Sun4c machines Full Name - PROM NAME */ +#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ +#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ +#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */ +#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */ +#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */ +#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */ +#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */ + +/* Sun4m machines, these predate the OpenBoot. These values only mean + * something if the value in the ARCH field is SM_SUN4M, if it is + * SM_SUN4M_OBP then you have the following situation: + * 1) You either have a sun4d, a sun4e, or a recently made sun4m. + * 2) You have to consult OpenBoot to determine which machine this is. + */ +#define SM_4M_SS60 0x01 /* Sun4m SparcSystem 600 */ +#define SM_4M_SS50 0x02 /* Sun4m SparcStation 10 */ +#define SM_4M_SS40 0x03 /* Sun4m SparcStation 5 */ + +/* Sun4d machines -- N/A */ +/* Sun4e machines -- N/A */ +/* Sun4u machines -- N/A */ + +#endif /* !(_SPARC_MACHINES_H) */ diff --git a/include/asm-m68k/machw.h b/include/asm-m68k/machw.h new file mode 100644 index 000000000000..d2e0e25d5c90 --- /dev/null +++ b/include/asm-m68k/machw.h @@ -0,0 +1,101 @@ +/* +** linux/machw.h -- This header defines some macros and pointers for +** the various Macintosh custom hardware registers. +** +** Copyright 1997 by Michael Schmitz +** +** 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_MACHW_H_ +#define _ASM_MACHW_H_ + +/* + * head.S maps the videomem to VIDEOMEMBASE + */ + +#define VIDEOMEMBASE 0xf0000000 +#define VIDEOMEMSIZE (4096*1024) +#define VIDEOMEMMASK (-4096*1024) + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> + +#if 0 +/* Mac SCSI Controller 5380 */ + +#define MAC_5380_BAS (0x50F10000) /* This is definitely wrong!! */ +struct MAC_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 mac_scsi ((*(volatile struct MAC_5380 *)MAC_5380_BAS)) + +/* +** SCC Z8530 +*/ + +#define MAC_SCC_BAS (0x50F04000) +struct MAC_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 mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS)) +#endif + +/* hardware stuff */ + +#define MACHW_DECLARE(name) unsigned name : 1 +#define MACHW_SET(name) (mac_hw_present.name = 1) +#define MACHW_PRESENT(name) (mac_hw_present.name) + +struct mac_hw_present { + /* video hardware */ + /* sound hardware */ + /* disk storage interfaces */ + MACHW_DECLARE(MAC_SCSI_80); /* Directly mapped NCR5380 */ + MACHW_DECLARE(MAC_SCSI_96); /* 53c9[46] */ + MACHW_DECLARE(MAC_SCSI_96_2); /* 2nd 53c9[46] Q900 and Q950 */ + MACHW_DECLARE(IDE); /* IDE Interface */ + /* other I/O hardware */ + MACHW_DECLARE(SCC); /* Serial Communications Contr. */ + /* DMA */ + MACHW_DECLARE(SCSI_DMA); /* DMA for the NCR5380 */ + /* real time clocks */ + MACHW_DECLARE(RTC_CLK); /* clock chip */ + /* supporting hardware */ + MACHW_DECLARE(VIA1); /* Versatile Interface Ad. 1 */ + MACHW_DECLARE(VIA2); /* Versatile Interface Ad. 2 */ + MACHW_DECLARE(RBV); /* Versatile Interface Ad. 2+ */ + /* NUBUS */ + MACHW_DECLARE(NUBUS); /* NUBUS */ +}; + +extern struct mac_hw_present mac_hw_present; + +#endif /* __ASSEMBLY__ */ + +#endif /* linux/machw.h */ diff --git a/include/asm-m68k/macintosh.h b/include/asm-m68k/macintosh.h new file mode 100644 index 000000000000..6fc3d19512d1 --- /dev/null +++ b/include/asm-m68k/macintosh.h @@ -0,0 +1,152 @@ +#ifndef __ASM_MACINTOSH_H +#define __ASM_MACINTOSH_H + +#include <linux/seq_file.h> +#include <linux/interrupt.h> + +/* + * Apple Macintoshisms + */ + +extern void mac_reset(void); +extern void mac_poweroff(void); +extern void mac_init_IRQ(void); +extern int mac_request_irq (unsigned int, irqreturn_t (*)(int, void *, + struct pt_regs *), + unsigned long, const char *, void *); +extern void mac_free_irq(unsigned int, void *); +extern void mac_enable_irq(unsigned int); +extern void mac_disable_irq(unsigned int); +extern int mac_irq_pending(unsigned int); +extern int show_mac_interrupts(struct seq_file *, void *); +#if 0 +extern void mac_default_handler(int irq); +#endif +extern void mac_identify(void); +extern void mac_report_hardware(void); +extern void mac_debugging_penguin(int); +extern void mac_boom(int); + +/* + * Floppy driver magic hook - probably shouldnt be here + */ + +extern void via1_set_head(int); + +extern void parse_booter(char *ptr); +extern void print_booter(char *ptr); + +/* + * Macintosh Table + */ + +struct mac_model +{ + short ident; + char *name; + char adb_type; + char via_type; + char scsi_type; + char ide_type; + char scc_type; + char ether_type; + char nubus_type; +}; + +#define MAC_ADB_NONE 0 +#define MAC_ADB_II 1 +#define MAC_ADB_IISI 2 +#define MAC_ADB_CUDA 3 +#define MAC_ADB_PB1 4 +#define MAC_ADB_PB2 5 +#define MAC_ADB_IOP 6 + +#define MAC_VIA_II 1 +#define MAC_VIA_IIci 2 +#define MAC_VIA_QUADRA 3 + +#define MAC_SCSI_NONE 0 +#define MAC_SCSI_OLD 1 +#define MAC_SCSI_QUADRA 2 +#define MAC_SCSI_QUADRA2 3 +#define MAC_SCSI_QUADRA3 4 + +#define MAC_IDE_NONE 0 +#define MAC_IDE_QUADRA 1 +#define MAC_IDE_PB 2 +#define MAC_IDE_BABOON 3 + +#define MAC_SCC_II 1 +#define MAC_SCC_IOP 2 +#define MAC_SCC_QUADRA 3 +#define MAC_SCC_PSC 4 + +#define MAC_ETHER_NONE 0 +#define MAC_ETHER_SONIC 1 +#define MAC_ETHER_MACE 2 + +#define MAC_NO_NUBUS 0 +#define MAC_NUBUS 1 + +/* + * Gestalt numbers + */ + +#define MAC_MODEL_II 6 +#define MAC_MODEL_IIX 7 +#define MAC_MODEL_IICX 8 +#define MAC_MODEL_SE30 9 +#define MAC_MODEL_IICI 11 +#define MAC_MODEL_IIFX 13 /* And well numbered it is too */ +#define MAC_MODEL_IISI 18 +#define MAC_MODEL_LC 19 +#define MAC_MODEL_Q900 20 +#define MAC_MODEL_PB170 21 +#define MAC_MODEL_Q700 22 +#define MAC_MODEL_CLII 23 /* aka: P200 */ +#define MAC_MODEL_PB140 25 +#define MAC_MODEL_Q950 26 /* aka: WGS95 */ +#define MAC_MODEL_LCIII 27 /* aka: P450 */ +#define MAC_MODEL_PB210 29 +#define MAC_MODEL_C650 30 +#define MAC_MODEL_PB230 32 +#define MAC_MODEL_PB180 33 +#define MAC_MODEL_PB160 34 +#define MAC_MODEL_Q800 35 /* aka: WGS80 */ +#define MAC_MODEL_Q650 36 +#define MAC_MODEL_LCII 37 /* aka: P400/405/410/430 */ +#define MAC_MODEL_PB250 38 +#define MAC_MODEL_IIVI 44 +#define MAC_MODEL_P600 45 /* aka: P600CD */ +#define MAC_MODEL_IIVX 48 +#define MAC_MODEL_CCL 49 /* aka: P250 */ +#define MAC_MODEL_PB165C 50 +#define MAC_MODEL_C610 52 /* aka: WGS60 */ +#define MAC_MODEL_Q610 53 +#define MAC_MODEL_PB145 54 /* aka: PB145B */ +#define MAC_MODEL_P520 56 /* aka: LC520 */ +#define MAC_MODEL_C660 60 +#define MAC_MODEL_P460 62 /* aka: LCIII+, P466/P467 */ +#define MAC_MODEL_PB180C 71 +#define MAC_MODEL_PB520 72 /* aka: PB520C, PB540, PB540C, PB550C */ +#define MAC_MODEL_PB270C 77 +#define MAC_MODEL_Q840 78 +#define MAC_MODEL_P550 80 /* aka: LC550, P560 */ +#define MAC_MODEL_CCLII 83 /* aka: P275 */ +#define MAC_MODEL_PB165 84 +#define MAC_MODEL_PB190 85 /* aka: PB190CS */ +#define MAC_MODEL_TV 88 +#define MAC_MODEL_P475 89 /* aka: LC475, P476 */ +#define MAC_MODEL_P475F 90 /* aka: P475 w/ FPU (no LC040) */ +#define MAC_MODEL_P575 92 /* aka: LC575, P577/P578 */ +#define MAC_MODEL_Q605 94 +#define MAC_MODEL_Q605_ACC 95 /* Q605 accelerated to 33 MHz */ +#define MAC_MODEL_Q630 98 /* aka: LC630, P630/631/635/636/637/638/640 */ +#define MAC_MODEL_P588 99 /* aka: LC580, P580 */ +#define MAC_MODEL_PB280 102 +#define MAC_MODEL_PB280C 103 +#define MAC_MODEL_PB150 115 + +extern struct mac_model *macintosh_config; + +#endif diff --git a/include/asm-m68k/macints.h b/include/asm-m68k/macints.h new file mode 100644 index 000000000000..fd8c3a9fea4d --- /dev/null +++ b/include/asm-m68k/macints.h @@ -0,0 +1,169 @@ +/* +** macints.h -- Macintosh Linux interrupt handling structs and prototypes +** +** Copyright 1997 by Michael Schmitz +** +** 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_MACINTS_H_ +#define _ASM_MACINTS_H_ + +#include <asm/irq.h> + +/* Setting this prints debugging info for unclaimed interrupts */ + +#define DEBUG_SPURIOUS + +/* Setting this prints debugging info on each autovector interrupt */ + +/* #define DEBUG_IRQS */ + +/* Setting this prints debugging info on each Nubus interrupt */ + +/* #define DEBUG_NUBUS_INT */ + +/* Setting this prints debugging info on irqs as they enabled and disabled. */ + +/* #define DEBUG_IRQUSE */ + +/* + * Base IRQ number for all Mac68K interrupt sources. Each source + * has eight indexes (base -> base+7). + */ + +#define VIA1_SOURCE_BASE 8 +#define VIA2_SOURCE_BASE 16 +#define MAC_SCC_SOURCE_BASE 24 +#define PSC3_SOURCE_BASE 24 +#define PSC4_SOURCE_BASE 32 +#define PSC5_SOURCE_BASE 40 +#define PSC6_SOURCE_BASE 48 +#define NUBUS_SOURCE_BASE 56 +#define BABOON_SOURCE_BASE 64 + +/* + * Maximum IRQ number is BABOON_SOURCE_BASE + 7, + * giving us IRQs up through 71 + */ + +#define NUM_MAC_SOURCES 72 + +/* + * clean way to separate IRQ into its source and index + */ + +#define IRQ_SRC(irq) (irq >> 3) +#define IRQ_IDX(irq) (irq & 7) + +#define IRQ_SPURIOUS (0) + +/* auto-vector interrupts */ +#define IRQ_AUTO_1 (1) +#define IRQ_AUTO_2 (2) +#define IRQ_AUTO_3 (3) +#define IRQ_AUTO_4 (4) +#define IRQ_AUTO_5 (5) +#define IRQ_AUTO_6 (6) +#define IRQ_AUTO_7 (7) + +/* VIA1 interrupts */ +#define IRQ_VIA1_0 (8) /* one second int. */ +#define IRQ_VIA1_1 (9) /* VBlank int. */ +#define IRQ_MAC_VBL IRQ_VIA1_1 +#define IRQ_VIA1_2 (10) /* ADB SR shifts complete */ +#define IRQ_MAC_ADB IRQ_VIA1_2 +#define IRQ_MAC_ADB_SR IRQ_VIA1_2 +#define IRQ_VIA1_3 (11) /* ADB SR CB2 ?? */ +#define IRQ_MAC_ADB_SD IRQ_VIA1_3 +#define IRQ_VIA1_4 (12) /* ADB SR ext. clock pulse */ +#define IRQ_MAC_ADB_CL IRQ_VIA1_4 +#define IRQ_VIA1_5 (13) +#define IRQ_MAC_TIMER_2 IRQ_VIA1_5 +#define IRQ_VIA1_6 (14) +#define IRQ_MAC_TIMER_1 IRQ_VIA1_6 +#define IRQ_VIA1_7 (15) + +/* VIA2/RBV interrupts */ +#define IRQ_VIA2_0 (16) +#define IRQ_MAC_SCSIDRQ IRQ_VIA2_0 +#define IRQ_VIA2_1 (17) +#define IRQ_MAC_NUBUS IRQ_VIA2_1 +#define IRQ_VIA2_2 (18) +#define IRQ_VIA2_3 (19) +#define IRQ_MAC_SCSI IRQ_VIA2_3 +#define IRQ_VIA2_4 (20) +#define IRQ_VIA2_5 (21) +#define IRQ_VIA2_6 (22) +#define IRQ_VIA2_7 (23) + +/* Level 3 (PSC, AV Macs only) interrupts */ +#define IRQ_PSC3_0 (24) +#define IRQ_MAC_MACE IRQ_PSC3_0 +#define IRQ_PSC3_1 (25) +#define IRQ_PSC3_2 (26) +#define IRQ_PSC3_3 (27) + +/* Level 4 (SCC) interrupts */ +#define IRQ_SCC (32) +#define IRQ_SCCA (33) +#define IRQ_SCCB (34) +#if 0 /* FIXME: are there multiple interrupt conditions on the SCC ?? */ +/* SCC interrupts */ +#define IRQ_SCCB_TX (32) +#define IRQ_SCCB_STAT (33) +#define IRQ_SCCB_RX (34) +#define IRQ_SCCB_SPCOND (35) +#define IRQ_SCCA_TX (36) +#define IRQ_SCCA_STAT (37) +#define IRQ_SCCA_RX (38) +#define IRQ_SCCA_SPCOND (39) +#endif + +/* Level 4 (PSC, AV Macs only) interrupts */ +#define IRQ_PSC4_0 (32) +#define IRQ_PSC4_1 (33) +#define IRQ_PSC4_2 (34) +#define IRQ_PSC4_3 (35) +#define IRQ_MAC_MACE_DMA IRQ_PSC4_3 + +/* Level 5 (PSC, AV Macs only) interrupts */ +#define IRQ_PSC5_0 (40) +#define IRQ_PSC5_1 (41) +#define IRQ_PSC5_2 (42) +#define IRQ_PSC5_3 (43) + +/* Level 6 (PSC, AV Macs only) interrupts */ +#define IRQ_PSC6_0 (48) +#define IRQ_PSC6_1 (49) +#define IRQ_PSC6_2 (50) +#define IRQ_PSC6_3 (51) + +/* Nubus interrupts (cascaded to VIA2) */ +#define IRQ_NUBUS_9 (56) +#define IRQ_NUBUS_A (57) +#define IRQ_NUBUS_B (58) +#define IRQ_NUBUS_C (59) +#define IRQ_NUBUS_D (60) +#define IRQ_NUBUS_E (61) +#define IRQ_NUBUS_F (62) + +/* Baboon interrupts (cascaded to nubus slot $C) */ +#define IRQ_BABOON_0 (64) +#define IRQ_BABOON_1 (65) +#define IRQ_BABOON_2 (66) +#define IRQ_BABOON_3 (67) + +#define SLOT2IRQ(x) (x + 47) +#define IRQ2SLOT(x) (x - 47) + +#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ +#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ + +extern irq_node_t *mac_irq_list[NUM_MAC_SOURCES]; +extern void mac_do_irq_list(int irq, struct pt_regs *); + +#endif /* asm/macints.h */ diff --git a/include/asm-m68k/math-emu.h b/include/asm-m68k/math-emu.h new file mode 100644 index 000000000000..7ac6259b68df --- /dev/null +++ b/include/asm-m68k/math-emu.h @@ -0,0 +1,300 @@ +#ifndef _ASM_M68K_SETUP_H +#define _ASM_M68K_SETUP_H + +#include <asm/setup.h> +#include <linux/linkage.h> + +/* Status Register bits */ + +/* accrued exception bits */ +#define FPSR_AEXC_INEX 3 +#define FPSR_AEXC_DZ 4 +#define FPSR_AEXC_UNFL 5 +#define FPSR_AEXC_OVFL 6 +#define FPSR_AEXC_IOP 7 + +/* exception status bits */ +#define FPSR_EXC_INEX1 8 +#define FPSR_EXC_INEX2 9 +#define FPSR_EXC_DZ 10 +#define FPSR_EXC_UNFL 11 +#define FPSR_EXC_OVFL 12 +#define FPSR_EXC_OPERR 13 +#define FPSR_EXC_SNAN 14 +#define FPSR_EXC_BSUN 15 + +/* quotient byte, assumes big-endian, of course */ +#define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1)) + +/* condition code bits */ +#define FPSR_CC_NAN 24 +#define FPSR_CC_INF 25 +#define FPSR_CC_Z 26 +#define FPSR_CC_NEG 27 + + +/* Control register bits */ + +/* rounding mode */ +#define FPCR_ROUND_RN 0 /* round to nearest/even */ +#define FPCR_ROUND_RZ 1 /* round to zero */ +#define FPCR_ROUND_RM 2 /* minus infinity */ +#define FPCR_ROUND_RP 3 /* plus infinity */ + +/* rounding precision */ +#define FPCR_PRECISION_X 0 /* long double */ +#define FPCR_PRECISION_S 1 /* double */ +#define FPCR_PRECISION_D 2 /* float */ + + +/* Flags to select the debugging output */ +#define PDECODE 0 +#define PEXECUTE 1 +#define PCONV 2 +#define PNORM 3 +#define PREGISTER 4 +#define PINSTR 5 +#define PUNIMPL 6 +#define PMOVEM 7 + +#define PMDECODE (1<<PDECODE) +#define PMEXECUTE (1<<PEXECUTE) +#define PMCONV (1<<PCONV) +#define PMNORM (1<<PNORM) +#define PMREGISTER (1<<PREGISTER) +#define PMINSTR (1<<PINSTR) +#define PMUNIMPL (1<<PUNIMPL) +#define PMMOVEM (1<<PMOVEM) + +#ifndef __ASSEMBLY__ + +#include <linux/kernel.h> +#include <linux/sched.h> + +union fp_mant64 { + unsigned long long m64; + unsigned long m32[2]; +}; + +union fp_mant128 { + unsigned long long m64[2]; + unsigned long m32[4]; +}; + +/* internal representation of extended fp numbers */ +struct fp_ext { + unsigned char lowmant; + unsigned char sign; + unsigned short exp; + union fp_mant64 mant; +}; + +/* C representation of FPU registers */ +/* NOTE: if you change this, you have to change the assembler offsets + below and the size in <asm/fpu.h>, too */ +struct fp_data { + struct fp_ext fpreg[8]; + unsigned int fpcr; + unsigned int fpsr; + unsigned int fpiar; + unsigned short prec; + unsigned short rnd; + struct fp_ext temp[2]; +}; + +#ifdef FPU_EMU_DEBUG +extern unsigned int fp_debugprint; + +#define dprint(bit, fmt, args...) ({ \ + if (fp_debugprint & (1 << (bit))) \ + printk(fmt, ## args); \ +}) +#else +#define dprint(bit, fmt, args...) +#endif + +#define uprint(str) ({ \ + static int __count = 3; \ + \ + if (__count > 0) { \ + printk("You just hit an unimplemented " \ + "fpu instruction (%s)\n", str); \ + printk("Please report this to ....\n"); \ + __count--; \ + } \ +}) + +#define FPDATA ((struct fp_data *)current->thread.fp) + +#else /* __ASSEMBLY__ */ + +#define FPDATA %a2 + +/* offsets from the base register to the floating point data in the task struct */ +#define FPD_FPREG (TASK_THREAD+THREAD_FPREG+0) +#define FPD_FPCR (TASK_THREAD+THREAD_FPREG+96) +#define FPD_FPSR (TASK_THREAD+THREAD_FPREG+100) +#define FPD_FPIAR (TASK_THREAD+THREAD_FPREG+104) +#define FPD_PREC (TASK_THREAD+THREAD_FPREG+108) +#define FPD_RND (TASK_THREAD+THREAD_FPREG+110) +#define FPD_TEMPFP1 (TASK_THREAD+THREAD_FPREG+112) +#define FPD_TEMPFP2 (TASK_THREAD+THREAD_FPREG+124) +#define FPD_SIZEOF (TASK_THREAD+THREAD_FPREG+136) + +/* offsets on the stack to access saved registers, + * these are only used during instruction decoding + * where we always know how deep we're on the stack. + */ +#define FPS_DO (PT_D0) +#define FPS_D1 (PT_D1) +#define FPS_D2 (PT_D2) +#define FPS_A0 (PT_A0) +#define FPS_A1 (PT_A1) +#define FPS_A2 (PT_A2) +#define FPS_SR (PT_SR) +#define FPS_PC (PT_PC) +#define FPS_EA (PT_PC+6) +#define FPS_PC2 (PT_PC+10) + +.macro fp_get_fp_reg + lea (FPD_FPREG,FPDATA,%d0.w*4),%a0 + lea (%a0,%d0.w*8),%a0 +.endm + +/* Macros used to get/put the current program counter. + * 020/030 use a different stack frame then 040/060, for the + * 040/060 the return pc points already to the next location, + * so this only needs to be modified for jump instructions. + */ +.macro fp_get_pc dest + move.l (FPS_PC+4,%sp),\dest +.endm + +.macro fp_put_pc src,jump=0 + move.l \src,(FPS_PC+4,%sp) +.endm + +.macro fp_get_instr_data f,s,dest,label + getuser \f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4) + addq.l #\s,%sp@(FPS_PC+4) +.endm + +.macro fp_get_instr_word dest,label,addr + fp_get_instr_data w,2,\dest,\label,\addr +.endm + +.macro fp_get_instr_long dest,label,addr + fp_get_instr_data l,4,\dest,\label,\addr +.endm + +/* These macros are used to read from/write to user space + * on error we jump to the fixup section, load the fault + * address into %a0 and jump to the exit. + * (derived from <asm/uaccess.h>) + */ +.macro getuser size,src,dest,label,addr +| printf ,"[\size<%08x]",1,\addr +.Lu1\@: moves\size \src,\dest + + .section .fixup,"ax" + .even +.Lu2\@: move.l \addr,%a0 + jra \label + .previous + + .section __ex_table,"a" + .align 4 + .long .Lu1\@,.Lu2\@ + .previous +.endm + +.macro putuser size,src,dest,label,addr +| printf ,"[\size>%08x]",1,\addr +.Lu1\@: moves\size \src,\dest +.Lu2\@: + + .section .fixup,"ax" + .even +.Lu3\@: move.l \addr,%a0 + jra \label + .previous + + .section __ex_table,"a" + .align 4 + .long .Lu1\@,.Lu3\@ + .long .Lu2\@,.Lu3\@ + .previous +.endm + + +.macro movestack nr,arg1,arg2,arg3,arg4,arg5 + .if \nr + movestack (\nr-1),\arg2,\arg3,\arg4,\arg5 + move.l \arg1,-(%sp) + .endif +.endm + +.macro printf bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5 +#ifdef FPU_EMU_DEBUG + .data +.Lpdata\@: + .string "\string" + .previous + + movem.l %d0/%d1/%a0/%a1,-(%sp) + .if \bit+1 +#if 0 + moveq #\bit,%d0 + andw #7,%d0 + btst %d0,fp_debugprint+((31-\bit)/8) +#else + btst #\bit,fp_debugprint+((31-\bit)/8) +#endif + jeq .Lpskip\@ + .endif + movestack \nr,\arg1,\arg2,\arg3,\arg4,\arg5 + pea .Lpdata\@ + jsr printk + lea ((\nr+1)*4,%sp),%sp +.Lpskip\@: + movem.l (%sp)+,%d0/%d1/%a0/%a1 +#endif +.endm + +.macro printx bit,fp +#ifdef FPU_EMU_DEBUG + movem.l %d0/%a0,-(%sp) + lea \fp,%a0 +#if 0 + moveq #'+',%d0 + tst.w (%a0) + jeq .Lx1\@ + moveq #'-',%d0 +.Lx1\@: printf \bit," %c",1,%d0 + move.l (4,%a0),%d0 + bclr #31,%d0 + jne .Lx2\@ + printf \bit,"0." + jra .Lx3\@ +.Lx2\@: printf \bit,"1." +.Lx3\@: printf \bit,"%08x%08x",2,%d0,%a0@(8) + move.w (2,%a0),%d0 + ext.l %d0 + printf \bit,"E%04x",1,%d0 +#else + printf \bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8) +#endif + movem.l (%sp)+,%d0/%a0 +#endif +.endm + +.macro debug instr,args +#ifdef FPU_EMU_DEBUG + \instr \args +#endif +.endm + + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_M68K_SETUP_H */ diff --git a/include/asm-m68k/mc146818rtc.h b/include/asm-m68k/mc146818rtc.h new file mode 100644 index 000000000000..11442095a8cf --- /dev/null +++ b/include/asm-m68k/mc146818rtc.h @@ -0,0 +1,26 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#include <linux/config.h> + +#ifdef CONFIG_ATARI +/* RTC in Atari machines */ + +#include <asm/atarihw.h> + +#define RTC_PORT(x) (TT_RTC_BAS + 2*(x)) + +#define CMOS_READ(addr) ({ \ +atari_outb_p((addr),RTC_PORT(0)); \ +atari_inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +atari_outb_p((addr),RTC_PORT(0)); \ +atari_outb_p((val),RTC_PORT(1)); \ +}) +#endif /* CONFIG_ATARI */ + +#endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-m68k/md.h b/include/asm-m68k/md.h new file mode 100644 index 000000000000..467ea08383e4 --- /dev/null +++ b/include/asm-m68k/md.h @@ -0,0 +1,13 @@ +/* $Id: md.h,v 1.1 1997/12/15 15:12:04 jj Exp $ + * md.h: High speed xor_block operation for RAID4/5 + * + */ + +#ifndef __ASM_MD_H +#define __ASM_MD_H + +/* #define HAVE_ARCH_XORBLOCK */ + +#define MD_XORBLOCK_ALIGNMENT sizeof(long) + +#endif /* __ASM_MD_H */ diff --git a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h new file mode 100644 index 000000000000..f831c4eeae6e --- /dev/null +++ b/include/asm-m68k/mman.h @@ -0,0 +1,43 @@ +#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_SEM 0x8 /* page may be used for atomic ops */ +#define PROT_NONE 0x0 /* page can not be accessed */ +#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ +#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ + +#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 MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ + +#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 */ + +#define MADV_NORMAL 0x0 /* default page-in behavior */ +#define MADV_RANDOM 0x1 /* page-in minimum required */ +#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ +#define MADV_WILLNEED 0x3 /* pre-fault pages */ +#define MADV_DONTNEED 0x4 /* discard these pages */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __M68K_MMAN_H__ */ diff --git a/include/asm-m68k/mmu.h b/include/asm-m68k/mmu.h new file mode 100644 index 000000000000..ccd36d26615a --- /dev/null +++ b/include/asm-m68k/mmu.h @@ -0,0 +1,7 @@ +#ifndef __MMU_H +#define __MMU_H + +/* Default "unsigned long" context */ +typedef unsigned long mm_context_t; + +#endif diff --git a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h new file mode 100644 index 000000000000..661191d15c81 --- /dev/null +++ b/include/asm-m68k/mmu_context.h @@ -0,0 +1,154 @@ +#ifndef __M68K_MMU_CONTEXT_H +#define __M68K_MMU_CONTEXT_H + +#include <linux/config.h> + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +#ifndef CONFIG_SUN3 + +#include <asm/setup.h> +#include <asm/page.h> +#include <asm/pgalloc.h> + +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + mm->context = virt_to_phys(mm->pgd); + return 0; +} + +#define destroy_context(mm) do { } while(0) + +static inline void switch_mm_0230(struct mm_struct *mm) +{ + unsigned long crp[2] = { + 0x80000000 | _PAGE_TABLE, mm->context + }; + unsigned long tmp; + + asm volatile (".chip 68030"); + + /* flush MC68030/MC68020 caches (they are virtually addressed) */ + asm volatile ( + "movec %%cacr,%0;" + "orw %1,%0; " + "movec %0,%%cacr" + : "=d" (tmp) : "di" (FLUSH_I_AND_D)); + + /* Switch the root pointer. For a 030-only kernel, + * avoid flushing the whole ATC, we only need to + * flush the user entries. The 68851 does this by + * itself. Avoid a runtime check here. + */ + asm volatile ( +#ifdef CPU_M68030_ONLY + "pmovefd %0,%%crp; " + "pflush #0,#4" +#else + "pmove %0,%%crp" +#endif + : : "m" (crp[0])); + + asm volatile (".chip 68k"); +} + +static inline void switch_mm_0460(struct mm_struct *mm) +{ + asm volatile (".chip 68040"); + + /* flush address translation cache (user entries) */ + asm volatile ("pflushan"); + + /* switch the root pointer */ + asm volatile ("movec %0,%%urp" : : "r" (mm->context)); + + if (CPU_IS_060) { + unsigned long tmp; + + /* clear user entries in the branch cache */ + asm volatile ( + "movec %%cacr,%0; " + "orl %1,%0; " + "movec %0,%%cacr" + : "=d" (tmp): "di" (0x00200000)); + } + + asm volatile (".chip 68k"); +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) +{ + if (prev != next) { + if (CPU_IS_020_OR_030) + switch_mm_0230(next); + else + switch_mm_0460(next); + } +} + +#define deactivate_mm(tsk,mm) do { } while (0) + +static inline void activate_mm(struct mm_struct *prev_mm, + struct mm_struct *next_mm) +{ + next_mm->context = virt_to_phys(next_mm->pgd); + + if (CPU_IS_020_OR_030) + switch_mm_0230(next_mm); + else + switch_mm_0460(next_mm); +} + +#else /* CONFIG_SUN3 */ +#include <asm/sun3mmu.h> +#include <linux/sched.h> + +extern unsigned long get_free_context(struct mm_struct *mm); +extern void clear_context(unsigned long context); + +/* set the context for a new task to unmapped */ +static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + mm->context = SUN3_INVALID_CONTEXT; + return 0; +} + +/* find the context given to this process, and if it hasn't already + got one, go get one for it. */ +static inline void get_mmu_context(struct mm_struct *mm) +{ + if(mm->context == SUN3_INVALID_CONTEXT) + mm->context = get_free_context(mm); +} + +/* flush context if allocated... */ +static inline void destroy_context(struct mm_struct *mm) +{ + if(mm->context != SUN3_INVALID_CONTEXT) + clear_context(mm->context); +} + +static inline void activate_context(struct mm_struct *mm) +{ + get_mmu_context(mm); + sun3_put_context(mm->context); +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) +{ + activate_context(tsk->mm); +} + +#define deactivate_mm(tsk,mm) do { } while (0) + +static inline void activate_mm(struct mm_struct *prev_mm, + struct mm_struct *next_mm) +{ + activate_context(next_mm); +} + +#endif +#endif diff --git a/include/asm-m68k/module.h b/include/asm-m68k/module.h new file mode 100644 index 000000000000..c6d75af2d8d3 --- /dev/null +++ b/include/asm-m68k/module.h @@ -0,0 +1,7 @@ +#ifndef _ASM_M68K_MODULE_H +#define _ASM_M68K_MODULE_H +struct mod_arch_specific { }; +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr +#endif /* _ASM_M68K_MODULE_H */ diff --git a/include/asm-m68k/motorola_pgalloc.h b/include/asm-m68k/motorola_pgalloc.h new file mode 100644 index 000000000000..5158412cd54d --- /dev/null +++ b/include/asm-m68k/motorola_pgalloc.h @@ -0,0 +1,107 @@ +#ifndef _MOTOROLA_PGALLOC_H +#define _MOTOROLA_PGALLOC_H + +#include <asm/tlb.h> +#include <asm/tlbflush.h> + +extern pmd_t *get_pointer_table(void); +extern int free_pointer_table(pmd_t *); + + +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +{ + pte_t *pte; + + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); + if (pte) { + __flush_page_to_ram(pte); + flush_tlb_kernel_page(pte); + nocache_page(pte); + } + + return pte; +} + +static inline void pte_free_kernel(pte_t *pte) +{ + cache_page(pte); + free_page((unsigned long) pte); +} + +static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) +{ + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); + pte_t *pte; + + if(!page) + return NULL; + + pte = kmap(page); + if (pte) { + __flush_page_to_ram(pte); + flush_tlb_kernel_page(pte); + nocache_page(pte); + } + kunmap(pte); + + return page; +} + +static inline void pte_free(struct page *page) +{ + cache_page(kmap(page)); + kunmap(page); + __free_page(page); +} + +static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *page) +{ + cache_page(kmap(page)); + kunmap(page); + __free_page(page); +} + + +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +{ + return get_pointer_table(); +} + +static inline int pmd_free(pmd_t *pmd) +{ + return free_pointer_table(pmd); +} + +static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) +{ + return free_pointer_table(pmd); +} + + +static inline void pgd_free(pgd_t *pgd) +{ + pmd_free((pmd_t *)pgd); +} + +static inline pgd_t *pgd_alloc(struct mm_struct *mm) +{ + return (pgd_t *)get_pointer_table(); +} + + +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) +{ + pmd_set(pmd, pte); +} + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page) +{ + pmd_set(pmd, page_address(page)); +} + +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) +{ + pgd_set(pgd, pmd); +} + +#endif /* _MOTOROLA_PGALLOC_H */ diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h new file mode 100644 index 000000000000..1628723458f5 --- /dev/null +++ b/include/asm-m68k/motorola_pgtable.h @@ -0,0 +1,294 @@ +#ifndef _MOTOROLA_PGTABLE_H +#define _MOTOROLA_PGTABLE_H + +#include <linux/config.h> + +/* + * 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_SUPER 0x080 /* 68040 supervisor only */ +#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ +#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) + +#define _PAGE_PROTNONE 0x004 +#define _PAGE_FILE 0x008 /* pagecache or swap? */ + +#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; + +/* This is the cache mode for normal pages, for supervisor access on + * processors >= '040. It is used in pte_mkcache(), and the variable is + * defined and initialized in head.S */ + +#if defined(CPU_M68060_ONLY) && defined(CONFIG_060_WRITETHROUGH) +#define m68k_supervisor_cachemode _PAGE_CACHE040W +#elif defined(CPU_M68040_OR_M68060_ONLY) +#define m68k_supervisor_cachemode _PAGE_CACHE040 +#elif defined(CPU_M68020_OR_M68030_ONLY) +#define m68k_supervisor_cachemode 0 +#else +extern int m68k_supervisor_cachemode; +#endif + +#if defined(CPU_M68040_OR_M68060_ONLY) +#define mm_cachebits _PAGE_CACHE040 +#elif defined(CPU_M68020_OR_M68030_ONLY) +#define mm_cachebits 0 +#else +extern unsigned long mm_cachebits; +#endif + +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _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_PROTNONE | _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 + +/* + * 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) pfn_pte(page_to_pfn(page), (pgprot)) + +static 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; +} + +static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) +{ + unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED; + unsigned long *ptr = pmdp->pmd; + short i = 16; + while (--i >= 0) { + *ptr++ = ptbl; + ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16); + } +} + +static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) +{ + pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); +} + +#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK)) +#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK)) +#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK)) + + +#define pte_none(pte) (!pte_val(pte)) +#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE)) +#define pte_clear(mm,addr,ptep) ({ pte_val(*(ptep)) = 0; }) + +#define pte_page(pte) (mem_map + ((unsigned long)(__va(pte_val(pte)) - PAGE_OFFSET) >> PAGE_SHIFT)) +#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_bad(pmd) ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE) +#define pmd_clear(pmdp) ({ \ + unsigned long *__ptr = pmdp->pmd; \ + short __i = 16; \ + while (--__i >= 0) \ + *__ptr++ = 0; \ +}) +#define pmd_page(pmd) (mem_map + ((unsigned long)(__va(pmd_val(pmd)) - PAGE_OFFSET) >> PAGE_SHIFT)) + + +#define pgd_none(pgd) (!pgd_val(pgd)) +#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE) +#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; }) + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_read(pte_t pte) { return 1; } +static inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); } +static inline int pte_exec(pte_t pte) { return 1; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } + +static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } +static inline pte_t pte_rdprotect(pte_t pte) { return pte; } +static inline pte_t pte_exprotect(pte_t pte) { return pte; } +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_RONLY; return pte; } +static inline pte_t pte_mkread(pte_t pte) { return pte; } +static inline pte_t pte_mkexec(pte_t pte) { return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mknocache(pte_t pte) +{ + pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode; + return pte; +} +static inline pte_t pte_mkcache(pte_t pte) +{ + pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; + return pte; +} + +#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) + +#define pgd_index(address) ((address) >> PGDIR_SHIFT) + +/* to find an entry in a page-table-directory */ +static inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address) +{ + return mm->pgd + pgd_index(address); +} + +#define swapper_pg_dir kernel_pg_dir +extern pgd_t kernel_pg_dir[128]; + +static 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.. */ +static 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.. */ +static inline pte_t *pte_offset_kernel(pmd_t *pmdp, unsigned long address) +{ + return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + +#define pte_offset_map(pmdp,address) ((pte_t *)kmap(pmd_page(*pmdp)) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) +#define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address) +#define pte_unmap(pte) kunmap(pte) +#define pte_unmap_nested(pte) kunmap(pte) + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any. + */ + +/* Prior to calling these routines, the page should have been flushed + * from both the cache and ATC, or the CPU might not notice that the + * cache setting for the page has been changed. -jskov + */ +static inline void nocache_page(void *vaddr) +{ + unsigned long addr = (unsigned long)vaddr; + + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + dir = pgd_offset_k(addr); + pmdp = pmd_offset(dir, addr); + ptep = pte_offset_kernel(pmdp, addr); + *ptep = pte_mknocache(*ptep); + } +} + +static inline void cache_page(void *vaddr) +{ + unsigned long addr = (unsigned long)vaddr; + + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + dir = pgd_offset_k(addr); + pmdp = pmd_offset(dir, addr); + ptep = pte_offset_kernel(pmdp, addr); + *ptep = pte_mkcache(*ptep); + } +} + +#define PTE_FILE_MAX_BITS 28 + +static inline unsigned long pte_to_pgoff(pte_t pte) +{ + return pte.pte >> 4; +} + +static inline pte_t pgoff_to_pte(unsigned off) +{ + pte_t pte = { (off << 4) + _PAGE_FILE }; + return pte; +} + +/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */ +#define __swp_type(x) (((x).val >> 4) & 0xff) +#define __swp_offset(x) ((x).val >> 12) +#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 4) | ((offset) << 12) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +#endif /* !__ASSEMBLY__ */ +#endif /* _MOTOROLA_PGTABLE_H */ diff --git a/include/asm-m68k/movs.h b/include/asm-m68k/movs.h new file mode 100644 index 000000000000..67dbea36960f --- /dev/null +++ b/include/asm-m68k/movs.h @@ -0,0 +1,55 @@ +#ifndef __MOVS_H__ +#define __MOVS_H__ + +/* +** movs.h +** +** Inline assembly macros to generate movs & related instructions +*/ + +/* Set DFC register value */ + +#define SET_DFC(x) \ + __asm__ __volatile__ (" movec %0,%/dfc" : : "d" (x)); + +/* Get DFC register value */ + +#define GET_DFC(x) \ + __asm__ __volatile__ (" movec %/dfc, %0" : "=d" (x) : ); + +/* Set SFC register value */ + +#define SET_SFC(x) \ + __asm__ __volatile__ (" movec %0,%/sfc" : : "d" (x)); + +/* Get SFC register value */ + +#define GET_SFC(x) \ + __asm__ __volatile__ (" movec %/sfc, %0" : "=d" (x) : ); + +#define SET_VBR(x) \ + __asm__ __volatile__ (" movec %0,%/vbr" : : "r" (x)); + +#define GET_VBR(x) \ + __asm__ __volatile__ (" movec %/vbr, %0" : "=g" (x) : ); + +/* Set a byte using the "movs" instruction */ + +#define SET_CONTROL_BYTE(addr,value) \ + __asm__ __volatile__ (" movsb %0, %1@" : : "d" (value), "a" (addr)); + +/* Get a byte using the "movs" instruction */ + +#define GET_CONTROL_BYTE(addr,value) \ + __asm__ __volatile__ (" movsb %1@, %0" : "=d" (value) : "a" (addr)); + +/* Set a (long)word using the "movs" instruction */ + +#define SET_CONTROL_WORD(addr,value) \ + __asm__ __volatile__ (" movsl %0, %1@" : : "d" (value), "a" (addr)); + +/* Get a (long)word using the "movs" instruction */ + +#define GET_CONTROL_WORD(addr,value) \ + __asm__ __volatile__ (" movsl %1@, %0" : "=d" (value) : "a" (addr)); +#endif diff --git a/include/asm-m68k/msgbuf.h b/include/asm-m68k/msgbuf.h new file mode 100644 index 000000000000..243cb798de8f --- /dev/null +++ b/include/asm-m68k/msgbuf.h @@ -0,0 +1,31 @@ +#ifndef _M68K_MSGBUF_H +#define _M68K_MSGBUF_H + +/* + * The msqid64_ds structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _M68K_MSGBUF_H */ diff --git a/include/asm-m68k/mvme147hw.h b/include/asm-m68k/mvme147hw.h new file mode 100644 index 000000000000..f245139f3671 --- /dev/null +++ b/include/asm-m68k/mvme147hw.h @@ -0,0 +1,111 @@ +#ifndef _MVME147HW_H_ +#define _MVME147HW_H_ + +typedef struct { + unsigned char + ctrl, + bcd_sec, + bcd_min, + bcd_hr, + bcd_dow, + bcd_dom, + bcd_mth, + bcd_year; +} MK48T02; + +#define RTC_WRITE 0x80 +#define RTC_READ 0x40 +#define RTC_STOP 0x20 + +#define m147_rtc ((MK48T02 * volatile)0xfffe07f8) + + +struct pcc_regs { + volatile u_long dma_tadr; + volatile u_long dma_dadr; + volatile u_long dma_bcr; + volatile u_long dma_hr; + volatile u_short t1_preload; + volatile u_short t1_count; + volatile u_short t2_preload; + volatile u_short t2_count; + volatile u_char t1_int_cntrl; + volatile u_char t1_cntrl; + volatile u_char t2_int_cntrl; + volatile u_char t2_cntrl; + volatile u_char ac_fail; + volatile u_char watchdog; + volatile u_char lpt_intr; + volatile u_char lpt_cntrl; + volatile u_char dma_intr; + volatile u_char dma_cntrl; + volatile u_char bus_error; + volatile u_char dma_status; + volatile u_char abort; + volatile u_char ta_fnctl; + volatile u_char serial_cntrl; + volatile u_char general_cntrl; + volatile u_char lan_cntrl; + volatile u_char general_status; + volatile u_char scsi_interrupt; + volatile u_char slave; + volatile u_char soft1_cntrl; + volatile u_char int_base; + volatile u_char soft2_cntrl; + volatile u_char revision_level; + volatile u_char lpt_data; + volatile u_char lpt_status; + }; + +#define m147_pcc ((struct pcc_regs * volatile)0xfffe1000) + + +#define PCC_INT_ENAB 0x08 + +#define PCC_TIMER_INT_CLR 0x80 +#define PCC_TIMER_PRELOAD 63936l + +#define PCC_LEVEL_ABORT 0x07 +#define PCC_LEVEL_SERIAL 0x04 +#define PCC_LEVEL_ETH 0x04 +#define PCC_LEVEL_TIMER1 0x04 +#define PCC_LEVEL_SCSI_PORT 0x04 +#define PCC_LEVEL_SCSI_DMA 0x04 + +#define PCC_IRQ_AC_FAIL 0x40 +#define PCC_IRQ_BERR 0x41 +#define PCC_IRQ_ABORT 0x42 +/* #define PCC_IRQ_SERIAL 0x43 */ +#define PCC_IRQ_PRINTER 0x47 +#define PCC_IRQ_TIMER1 0x48 +#define PCC_IRQ_TIMER2 0x49 +#define PCC_IRQ_SOFTWARE1 0x4a +#define PCC_IRQ_SOFTWARE2 0x4b + + +#define M147_SCC_A_ADDR 0xfffe3002 +#define M147_SCC_B_ADDR 0xfffe3000 +#define M147_SCC_PCLK 5000000 + +#define MVME147_IRQ_SCSI_PORT 0x45 +#define MVME147_IRQ_SCSI_DMA 0x46 + +/* SCC interrupts, for MVME147 */ + +#define MVME147_IRQ_TYPE_PRIO 0 +#define MVME147_IRQ_SCC_BASE 0x60 +#define MVME147_IRQ_SCCB_TX 0x60 +#define MVME147_IRQ_SCCB_STAT 0x62 +#define MVME147_IRQ_SCCB_RX 0x64 +#define MVME147_IRQ_SCCB_SPCOND 0x66 +#define MVME147_IRQ_SCCA_TX 0x68 +#define MVME147_IRQ_SCCA_STAT 0x6a +#define MVME147_IRQ_SCCA_RX 0x6c +#define MVME147_IRQ_SCCA_SPCOND 0x6e + +#define MVME147_LANCE_BASE 0xfffe1800 +#define MVME147_LANCE_IRQ 0x44 + +#define ETHERNET_ADDRESS 0xfffe0778 + +#endif diff --git a/include/asm-m68k/mvme16xhw.h b/include/asm-m68k/mvme16xhw.h new file mode 100644 index 000000000000..5d07231d2426 --- /dev/null +++ b/include/asm-m68k/mvme16xhw.h @@ -0,0 +1,111 @@ +#ifndef _M68K_MVME16xHW_H_ +#define _M68K_MVME16xHW_H_ + +#include <asm/irq.h> + +/* Board ID data structure - pointer to this retrieved from Bug by head.S */ + +/* Note, bytes 12 and 13 are board no in BCD (0162,0166,0167,0177,etc) */ + +extern long mvme_bdid_ptr; + +typedef struct { + char bdid[4]; + u_char rev, mth, day, yr; + u_short size, reserved; + u_short brdno; + char brdsuffix[2]; + u_long options; + u_short clun, dlun, ctype, dnum; + u_long option2; +} t_bdid, *p_bdid; + + +typedef struct { + u_char ack_icr, + flt_icr, + sel_icr, + pe_icr, + bsy_icr, + spare1, + isr, + cr, + spare2, + spare3, + spare4, + data; +} MVMElp, *MVMElpPtr; + +#define MVME_LPR_BASE 0xfff42030 + +#define mvmelp ((*(volatile MVMElpPtr)(MVME_LPR_BASE))) + +typedef struct { + unsigned char + ctrl, + bcd_sec, + bcd_min, + bcd_hr, + bcd_dow, + bcd_dom, + bcd_mth, + bcd_year; +} MK48T08_t, *MK48T08ptr_t; + +#define RTC_WRITE 0x80 +#define RTC_READ 0x40 +#define RTC_STOP 0x20 + +#define MVME_RTC_BASE 0xfffc1ff8 + +#define MVME_I596_BASE 0xfff46000 + +#define MVME_SCC_A_ADDR 0xfff45005 +#define MVME_SCC_B_ADDR 0xfff45001 +#define MVME_SCC_PCLK 10000000 + +#define MVME162_IRQ_TYPE_PRIO 0 + +#define MVME167_IRQ_PRN 0x54 +#define MVME16x_IRQ_I596 0x57 +#define MVME16x_IRQ_SCSI 0x55 +#define MVME16x_IRQ_FLY 0x7f +#define MVME167_IRQ_SER_ERR 0x5c +#define MVME167_IRQ_SER_MODEM 0x5d +#define MVME167_IRQ_SER_TX 0x5e +#define MVME167_IRQ_SER_RX 0x5f +#define MVME16x_IRQ_TIMER 0x59 +#define MVME167_IRQ_ABORT 0x6e +#define MVME162_IRQ_ABORT 0x5e + +/* SCC interrupts, for MVME162 */ +#define MVME162_IRQ_SCC_BASE 0x40 +#define MVME162_IRQ_SCCB_TX 0x40 +#define MVME162_IRQ_SCCB_STAT 0x42 +#define MVME162_IRQ_SCCB_RX 0x44 +#define MVME162_IRQ_SCCB_SPCOND 0x46 +#define MVME162_IRQ_SCCA_TX 0x48 +#define MVME162_IRQ_SCCA_STAT 0x4a +#define MVME162_IRQ_SCCA_RX 0x4c +#define MVME162_IRQ_SCCA_SPCOND 0x4e + +/* MVME162 version register */ + +#define MVME162_VERSION_REG 0xfff4202e + +extern unsigned short mvme16x_config; + +/* Lower 8 bits must match the revision register in the MC2 chip */ + +#define MVME16x_CONFIG_SPEED_32 0x0001 +#define MVME16x_CONFIG_NO_VMECHIP2 0x0002 +#define MVME16x_CONFIG_NO_SCSICHIP 0x0004 +#define MVME16x_CONFIG_NO_ETHERNET 0x0008 +#define MVME16x_CONFIG_GOT_FPU 0x0010 + +#define MVME16x_CONFIG_GOT_LP 0x0100 +#define MVME16x_CONFIG_GOT_CD2401 0x0200 +#define MVME16x_CONFIG_GOT_SCCA 0x0400 +#define MVME16x_CONFIG_GOT_SCCB 0x0800 + +#endif diff --git a/include/asm-m68k/namei.h b/include/asm-m68k/namei.h new file mode 100644 index 000000000000..f33f243b644a --- /dev/null +++ b/include/asm-m68k/namei.h @@ -0,0 +1,17 @@ +/* + * linux/include/asm-m68k/namei.h + * + * Included from linux/fs/namei.c + */ + +#ifndef __M68K_NAMEI_H +#define __M68K_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif diff --git a/include/asm-m68k/nubus.h b/include/asm-m68k/nubus.h new file mode 100644 index 000000000000..d6be9976f1ae --- /dev/null +++ b/include/asm-m68k/nubus.h @@ -0,0 +1,46 @@ +#ifndef _ASM_M68K_NUBUS_H +#define _ASM_M68K_NUBUS_H + +#include <asm/raw_io.h> + +#define nubus_readb raw_inb +#define nubus_readw raw_inw +#define nubus_readl raw_inl + +#define nubus_writeb raw_outb +#define nubus_writew raw_outw +#define nubus_writel raw_outl + +#define nubus_memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define nubus_memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define nubus_memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +static inline void *nubus_remap_nocache_ser(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +static inline void *nubus_remap_nocache_nonser(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER); +} + +static inline void *nbus_remap_writethrough(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} + +static inline void *nubus_remap_fullcache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +#define nubus_unmap iounmap +#define nubus_iounmap iounmap +#define nubus_ioremap nubus_remap_nocache_ser + +#endif /* _ASM_NUBUS_H */ diff --git a/include/asm-m68k/openprom.h b/include/asm-m68k/openprom.h new file mode 100644 index 000000000000..efbfb0bec6e2 --- /dev/null +++ b/include/asm-m68k/openprom.h @@ -0,0 +1,314 @@ +/* $Id: openprom.h,v 1.19 1996/09/25 03:51:08 davem Exp $ */ +#ifndef __SPARC_OPENPROM_H +#define __SPARC_OPENPROM_H + +/* openprom.h: Prom structures and defines for access to the OPENBOOT + * prom routines and data areas. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#include <linux/config.h> + +/* Empirical constants... */ +#ifdef CONFIG_SUN3 +#define KADB_DEBUGGER_BEGVM 0x0fee0000 /* There is no kadb yet but...*/ +#define LINUX_OPPROM_BEGVM 0x0fef0000 +#define LINUX_OPPROM_ENDVM 0x0ff10000 /* I think this is right - tm */ +#else +#define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */ +#define LINUX_OPPROM_BEGVM 0xffd00000 +#define LINUX_OPPROM_ENDVM 0xfff00000 +#define LINUX_OPPROM_MAGIC 0x10010407 +#endif + +#ifndef __ASSEMBLY__ +/* V0 prom device operations. */ +struct linux_dev_v0_funcs { + int (*v0_devopen)(char *device_str); + int (*v0_devclose)(int dev_desc); + int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_seekdev)(int dev_desc, long logical_offst, int from); +}; + +/* V2 and later prom device operations. */ +struct linux_dev_v2_funcs { + int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ + char * (*v2_dumb_mem_alloc)(char *va, unsigned sz); + void (*v2_dumb_mem_free)(char *va, unsigned sz); + + /* To map devices into virtual I/O space. */ + char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz); + void (*v2_dumb_munmap)(char *virta, unsigned size); + + int (*v2_dev_open)(char *devpath); + void (*v2_dev_close)(int d); + int (*v2_dev_read)(int d, char *buf, int nbytes); + int (*v2_dev_write)(int d, char *buf, int nbytes); + int (*v2_dev_seek)(int d, int hi, int lo); + + /* Never issued (multistage load support) */ + void (*v2_wheee2)(void); + void (*v2_wheee3)(void); +}; + +struct linux_mlist_v0 { + struct linux_mlist_v0 *theres_more; + char *start_adr; + unsigned num_bytes; +}; + +struct linux_mem_v0 { + struct linux_mlist_v0 **v0_totphys; + struct linux_mlist_v0 **v0_prommap; + struct linux_mlist_v0 **v0_available; /* What we can use */ +}; + +/* Arguments sent to the kernel from the boot prompt. */ +struct linux_arguments_v0 { + char *argv[8]; + char args[100]; + char boot_dev[2]; + int boot_dev_ctrl; + int boot_dev_unit; + int dev_partition; + char *kernel_file_name; + void *aieee1; /* XXX */ +}; + +/* V2 and up boot things. */ +struct linux_bootargs_v2 { + char **bootpath; + char **bootargs; + int *fd_stdin; + int *fd_stdout; +}; + +#if defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) +struct linux_romvec { + char *pv_initsp; + int (*pv_startmon)(void); + + int *diagberr; + + struct linux_arguments_v0 **pv_v0bootargs; + unsigned *pv_sun3mem; + + unsigned char (*pv_getchar)(void); + int (*pv_putchar)(int ch); + int (*pv_nbgetchar)(void); + int (*pv_nbputchar)(int ch); + unsigned char *pv_echo; + unsigned char *pv_insource; + unsigned char *pv_outsink; + + int (*pv_getkey)(void); + int (*pv_initgetkey)(void); + unsigned int *pv_translation; + unsigned char *pv_keybid; + int *pv_screen_x; + int *pv_screen_y; + struct keybuf *pv_keybuf; + + char *pv_monid; + + /* + * Frame buffer output and terminal emulation + */ + + int (*pv_fbwritechar)(char); + int *pv_fbaddr; + char **pv_font; + int (*pv_fbwritestr)(char); + + void (*pv_reboot)(char *bootstr); + + /* + * Line input and parsing + */ + + unsigned char *pv_linebuf; + unsigned char **pv_lineptr; + int *pv_linesize; + int (*pv_getline)(void); + unsigned char (*pv_getnextchar)(void); + unsigned char (*pv_peeknextchar)(void); + int *pv_fbthere; + int (*pv_getnum)(void); + + void (*pv_printf)(const char *fmt, ...); + int (*pv_printhex)(void); + + unsigned char *pv_leds; + int (*pv_setleds)(void); + + /* + * Non-maskable interrupt (nmi) information + */ + + int (*pv_nmiaddr)(void); + int (*pv_abortentry)(void); + int *pv_nmiclock; + + int *pv_fbtype; + + /* + * Assorted other things + */ + + unsigned pv_romvers; + struct globram *pv_globram; + char *pv_kbdzscc; + + int *pv_keyrinit; + unsigned char *pv_keyrtick; + unsigned *pv_memoryavail; + long *pv_resetaddr; + long *pv_resetmap; + + void (*pv_halt)(void); + unsigned char *pv_memorybitmap; + +#ifdef CONFIG_SUN3 + void (*pv_setctxt)(int ctxt, char *va, int pmeg); + void (*pv_vector_cmd)(void); + int dummy1z; + int dummy2z; + int dummy3z; + int dummy4z; +#endif +}; +#else +/* The top level PROM vector. */ +struct linux_romvec { + /* Version numbers. */ + unsigned int pv_magic_cookie; + unsigned int pv_romvers; + unsigned int pv_plugin_revision; + unsigned int pv_printrev; + + /* Version 0 memory descriptors. */ + struct linux_mem_v0 pv_v0mem; + + /* Node operations. */ + struct linux_nodeops *pv_nodeops; + + char **pv_bootstr; + struct linux_dev_v0_funcs pv_v0devops; + + char *pv_stdin; + char *pv_stdout; +#define PROMDEV_KBD 0 /* input from keyboard */ +#define PROMDEV_SCREEN 0 /* output to screen */ +#define PROMDEV_TTYA 1 /* in/out to ttya */ +#define PROMDEV_TTYB 2 /* in/out to ttyb */ + + /* Blocking getchar/putchar. NOT REENTRANT! (grr) */ + int (*pv_getchar)(void); + void (*pv_putchar)(int ch); + + /* Non-blocking variants. */ + int (*pv_nbgetchar)(void); + int (*pv_nbputchar)(int ch); + + void (*pv_putstr)(char *str, int len); + + /* Miscellany. */ + void (*pv_reboot)(char *bootstr); + void (*pv_printf)(__const__ char *fmt, ...); + void (*pv_abort)(void); + __volatile__ int *pv_ticks; + void (*pv_halt)(void); + void (**pv_synchook)(void); + + /* Evaluate a forth string, not different proto for V0 and V2->up. */ + union { + void (*v0_eval)(int len, char *str); + void (*v2_eval)(char *str); + } pv_fortheval; + + struct linux_arguments_v0 **pv_v0bootargs; + + /* Get ether address. */ + unsigned int (*pv_enaddr)(int d, char *enaddr); + + struct linux_bootargs_v2 pv_v2bootargs; + struct linux_dev_v2_funcs pv_v2devops; + + int filler[15]; + + /* This one is sun4c/sun4 only. */ + void (*pv_setctxt)(int ctxt, char *va, int pmeg); + + /* Prom version 3 Multiprocessor routines. This stuff is crazy. + * No joke. Calling these when there is only one cpu probably + * crashes the machine, have to test this. :-) + */ + + /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context + * 'thiscontext' executing at address 'prog_counter' + */ + int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr, + int thiscontext, char *prog_counter); + + /* v3_cpustop() will cause cpu 'whichcpu' to stop executing + * until a resume cpu call is made. + */ + int (*v3_cpustop)(unsigned int whichcpu); + + /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or + * resume cpu call is made. + */ + int (*v3_cpuidle)(unsigned int whichcpu); + + /* v3_cpuresume() will resume processor 'whichcpu' executing + * starting with whatever 'pc' and 'npc' were left at the + * last 'idle' or 'stop' call. + */ + int (*v3_cpuresume)(unsigned int whichcpu); +}; +#endif + +/* Routines for traversing the prom device tree. */ +struct linux_nodeops { + int (*no_nextnode)(int node); + int (*no_child)(int node); + int (*no_proplen)(int node, char *name); + int (*no_getprop)(int node, char *name, char *val); + int (*no_setprop)(int node, char *name, char *val, int len); + char * (*no_nextprop)(int node, char *name); +}; + +/* More fun PROM structures for device probing. */ +#define PROMREG_MAX 16 +#define PROMVADDR_MAX 16 +#define PROMINTR_MAX 15 + +struct linux_prom_registers { + int which_io; /* is this in OBIO space? */ + char *phys_addr; /* The physical address of this register */ + int reg_size; /* How many bytes does this register take up? */ +}; + +struct linux_prom_irqs { + int pri; /* IRQ priority */ + int vector; /* This is foobar, what does it do? */ +}; + +/* Element of the "ranges" vector */ +struct linux_prom_ranges { + unsigned int ot_child_space; + unsigned int ot_child_base; /* Bus feels this */ + unsigned int ot_parent_space; + unsigned int ot_parent_base; /* CPU looks from here */ + unsigned int or_size; +}; + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC_OPENPROM_H) */ diff --git a/include/asm-m68k/oplib.h b/include/asm-m68k/oplib.h new file mode 100644 index 000000000000..c3594f473ef7 --- /dev/null +++ b/include/asm-m68k/oplib.h @@ -0,0 +1,297 @@ +/* $Id: oplib.h,v 1.12 1996/10/31 06:29:13 davem Exp $ + * oplib.h: Describes the interface and available routines in the + * Linux Prom library. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC_OPLIB_H +#define __SPARC_OPLIB_H + +#include <asm/openprom.h> + +/* The master romvec pointer... */ +extern struct linux_romvec *romvec; + +/* Enumeration to describe the prom major version we have detected. */ +enum prom_major_version { + PROM_V0, /* Original sun4c V0 prom */ + PROM_V2, /* sun4c and early sun4m V2 prom */ + PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */ + PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */ + PROM_AP1000, /* actually no prom at all */ +}; + +extern enum prom_major_version prom_vers; +/* Revision, and firmware revision. */ +extern unsigned int prom_rev, prom_prev; + +/* Root node of the prom device tree, this stays constant after + * initialization is complete. + */ +extern int prom_root_node; + +/* Pointer to prom structure containing the device tree traversal + * and usage utility functions. Only prom-lib should use these, + * users use the interface defined by the library only! + */ +extern struct linux_nodeops *prom_nodeops; + +/* The functions... */ + +/* You must call prom_init() before using any of the library services, + * preferably as early as possible. Pass it the romvec pointer. + */ +extern void prom_init(struct linux_romvec *rom_ptr); + +/* Boot argument acquisition, returns the boot command line string. */ +extern char *prom_getbootargs(void); + +/* Device utilities. */ + +/* Map and unmap devices in IO space at virtual addresses. Note that the + * virtual address you pass is a request and the prom may put your mappings + * somewhere else, so check your return value as that is where your new + * mappings really are! + * + * Another note, these are only available on V2 or higher proms! + */ +extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); +extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); + +/* Device operations. */ + +/* Open the device described by the passed string. Note, that the format + * of the string is different on V0 vs. V2->higher proms. The caller must + * know what he/she is doing! Returns the device descriptor, an int. + */ +extern int prom_devopen(char *device_string); + +/* Close a previously opened device described by the passed integer + * descriptor. + */ +extern int prom_devclose(int device_handle); + +/* Do a seek operation on the device described by the passed integer + * descriptor. + */ +extern void prom_seek(int device_handle, unsigned int seek_hival, + unsigned int seek_lowval); + +/* Machine memory configuration routine. */ + +/* This function returns a V0 format memory descriptor table, it has three + * entries. One for the total amount of physical ram on the machine, one + * for the amount of physical ram available, and one describing the virtual + * areas which are allocated by the prom. So, in a sense the physical + * available is a calculation of the total physical minus the physical mapped + * by the prom with virtual mappings. + * + * These lists are returned pre-sorted, this should make your life easier + * since the prom itself is way too lazy to do such nice things. + */ +extern struct linux_mem_v0 *prom_meminfo(void); + +/* Miscellaneous routines, don't really fit in any category per se. */ + +/* Reboot the machine with the command line passed. */ +extern void prom_reboot(char *boot_command); + +/* Evaluate the forth string passed. */ +extern void prom_feval(char *forth_string); + +/* Enter the prom, with possibility of continuation with the 'go' + * command in newer proms. + */ +extern void prom_cmdline(void); + +/* Enter the prom, with no chance of continuation for the stand-alone + * which calls this. + */ +extern void prom_halt(void); + +/* Set the PROM 'sync' callback function to the passed function pointer. + * When the user gives the 'sync' command at the prom prompt while the + * kernel is still active, the prom will call this routine. + * + * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX + */ +typedef void (*sync_func_t)(void); +extern void prom_setsync(sync_func_t func_ptr); + +/* Acquire the IDPROM of the root node in the prom device tree. This + * gets passed a buffer where you would like it stuffed. The return value + * is the format type of this idprom or 0xff on error. + */ +extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); + +/* Get the prom major version. */ +extern int prom_version(void); + +/* Get the prom plugin revision. */ +extern int prom_getrev(void); + +/* Get the prom firmware revision. */ +extern int prom_getprev(void); + +/* Character operations to/from the console.... */ + +/* Non-blocking get character from console. */ +extern int prom_nbgetchar(void); + +/* Non-blocking put character to console. */ +extern int prom_nbputchar(char character); + +/* Blocking get character from console. */ +extern char prom_getchar(void); + +/* Blocking put character to console. */ +extern void prom_putchar(char character); + +/* Prom's internal printf routine, don't use in kernel/boot code. */ +void prom_printf(char *fmt, ...); + +/* Query for input device type */ + +enum prom_input_device { + PROMDEV_IKBD, /* input from keyboard */ + PROMDEV_ITTYA, /* input from ttya */ + PROMDEV_ITTYB, /* input from ttyb */ + PROMDEV_I_UNK, +}; + +extern enum prom_input_device prom_query_input_device(void); + +/* Query for output device type */ + +enum prom_output_device { + PROMDEV_OSCREEN, /* to screen */ + PROMDEV_OTTYA, /* to ttya */ + PROMDEV_OTTYB, /* to ttyb */ + PROMDEV_O_UNK, +}; + +extern enum prom_output_device prom_query_output_device(void); + +/* Multiprocessor operations... */ + +/* Start the CPU with the given device tree node, context table, and context + * at the passed program counter. + */ +extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table, + int context, char *program_counter); + +/* Stop the CPU with the passed device tree node. */ +extern int prom_stopcpu(int cpunode); + +/* Idle the CPU with the passed device tree node. */ +extern int prom_idlecpu(int cpunode); + +/* Re-Start the CPU with the passed device tree node. */ +extern int prom_restartcpu(int cpunode); + +/* PROM memory allocation facilities... */ + +/* Allocated at possibly the given virtual address a chunk of the + * indicated size. + */ +extern char *prom_alloc(char *virt_hint, unsigned int size); + +/* Free a previously allocated chunk. */ +extern void prom_free(char *virt_addr, unsigned int size); + +/* Sun4/sun4c specific memory-management startup hook. */ + +/* Map the passed segment in the given context at the passed + * virtual address. + */ +extern void prom_putsegment(int context, unsigned long virt_addr, + int physical_segment); + +/* PROM device tree traversal functions... */ + +/* Get the child node of the given node, or zero if no child exists. */ +extern int prom_getchild(int parent_node); + +/* Get the next sibling node of the given node, or zero if no further + * siblings exist. + */ +extern int prom_getsibling(int node); + +/* Get the length, at the passed node, of the given property type. + * Returns -1 on error (ie. no such property at this node). + */ +extern int prom_getproplen(int thisnode, char *property); + +/* Fetch the requested property using the given buffer. Returns + * the number of bytes the prom put into your buffer or -1 on error. + */ +extern int prom_getproperty(int thisnode, char *property, + char *prop_buffer, int propbuf_size); + +/* Acquire an integer property. */ +extern int prom_getint(int node, char *property); + +/* Acquire an integer property, with a default value. */ +extern int prom_getintdefault(int node, char *property, int defval); + +/* Acquire a boolean property, 0=FALSE 1=TRUE. */ +extern int prom_getbool(int node, char *prop); + +/* Acquire a string property, null string on error. */ +extern void prom_getstring(int node, char *prop, char *buf, int bufsize); + +/* Does the passed node have the given "name"? YES=1 NO=0 */ +extern int prom_nodematch(int thisnode, char *name); + +/* Puts in buffer a prom name in the form name@x,y or name (x for which_io + * and y for first regs phys address + */ +extern int prom_getname(int node, char *buf, int buflen); + +/* Search all siblings starting at the passed node for "name" matching + * the given string. Returns the node on success, zero on failure. + */ +extern int prom_searchsiblings(int node_start, char *name); + +/* Return the first property type, as a string, for the given node. + * Returns a null string on error. + */ +extern char *prom_firstprop(int node); + +/* Returns the next property after the passed property for the given + * node. Returns null string on failure. + */ +extern char *prom_nextprop(int node, char *prev_property); + +/* Returns 1 if the specified node has given property. */ +extern int prom_node_has_property(int node, char *property); + +/* Set the indicated property at the given node with the passed value. + * Returns the number of bytes of your value that the prom took. + */ +extern int prom_setprop(int node, char *prop_name, char *prop_value, + int value_size); + +extern int prom_pathtoinode(char *path); +extern int prom_inst2pkg(int); + +/* Dorking with Bus ranges... */ + +/* Adjust reg values with the passed ranges. */ +extern void prom_adjust_regs(struct linux_prom_registers *regp, int nregs, + struct linux_prom_ranges *rangep, int nranges); + +/* Adjust child ranges with the passed parent ranges. */ +extern void prom_adjust_ranges(struct linux_prom_ranges *cranges, int ncranges, + struct linux_prom_ranges *pranges, int npranges); + +/* Apply promlib probed OBIO ranges to registers. */ +extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs); + +/* Apply ranges of any prom node (and optionally parent node as well) to registers. */ +extern void prom_apply_generic_ranges(int node, int parent, + struct linux_prom_registers *sbusregs, int nregs); + + +#endif /* !(__SPARC_OPLIB_H) */ diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h new file mode 100644 index 000000000000..99a516709210 --- /dev/null +++ b/include/asm-m68k/page.h @@ -0,0 +1,195 @@ +#ifndef _M68K_PAGE_H +#define _M68K_PAGE_H + +#include <linux/config.h> + +/* PAGE_SHIFT determines the page size */ +#ifndef CONFIG_SUN3 +#define PAGE_SHIFT (12) +#else +#define PAGE_SHIFT (13) +#endif +#ifdef __ASSEMBLY__ +#define PAGE_SIZE (1 << PAGE_SHIFT) +#else +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#endif +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#include <asm/setup.h> + +#if PAGE_SHIFT < 13 +#define THREAD_SIZE (8192) +#else +#define THREAD_SIZE PAGE_SIZE +#endif + +#ifndef __ASSEMBLY__ + +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +/* + * We don't need to check for alignment etc. + */ +#ifdef CPU_M68040_OR_M68060_ONLY +static inline void copy_page(void *to, void *from) +{ + unsigned long tmp; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %1@+,%0@+\n\t" + "move16 %1@+,%0@+\n\t" + ".chip 68k\n\t" + "dbra %2,1b\n\t" + : "=a" (to), "=a" (from), "=d" (tmp) + : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1) + ); +} + +static inline void clear_page(void *page) +{ + unsigned long tmp; + unsigned long *sp = page; + + *sp++ = 0; + *sp++ = 0; + *sp++ = 0; + *sp++ = 0; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %2@+,%0@+\n\t" + ".chip 68k\n\t" + "subqw #8,%2\n\t" + "subqw #8,%2\n\t" + "dbra %1,1b\n\t" + : "=a" (sp), "=d" (tmp) + : "a" (page), "0" (sp), + "1" ((PAGE_SIZE - 16) / 16 - 1)); +} + +#else +#define clear_page(page) memset((page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) +#endif + +#define clear_user_page(addr, vaddr, page) \ + do { clear_page(addr); \ + flush_dcache_page(page); \ + } while (0) +#define copy_user_page(to, from, vaddr, page) \ + do { copy_page(to, from); \ + flush_dcache_page(page); \ + } while (0) + +/* + * 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) } ) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +/* Pure 2^n version of get_order */ +static inline int get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +#endif /* !__ASSEMBLY__ */ + +#include <asm/page_offset.h> + +#define PAGE_OFFSET (PAGE_OFFSET_RAW) + +#ifndef __ASSEMBLY__ + +#ifndef CONFIG_SUN3 + +#define WANT_PAGE_VIRTUAL +#ifdef CONFIG_SINGLE_MEMORY_CHUNK +extern unsigned long m68k_memoffset; + +#define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset) +#define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset)) +#else +#define __pa(vaddr) virt_to_phys((void *)vaddr) +#define __va(paddr) phys_to_virt((unsigned long)paddr) +#endif + +#else /* !CONFIG_SUN3 */ +/* This #define is a horrible hack to suppress lots of warnings. --m */ +#define __pa(x) ___pa((unsigned long)x) +static inline unsigned long ___pa(unsigned long x) +{ + if(x == 0) + return 0; + if(x >= PAGE_OFFSET) + return (x-PAGE_OFFSET); + else + return (x+0x2000000); +} + +static inline void *__va(unsigned long x) +{ + if(x == 0) + return (void *)0; + + if(x < 0x2000000) + return (void *)(x+PAGE_OFFSET); + else + return (void *)(x-0x2000000); +} +#endif /* CONFIG_SUN3 */ + +/* + * NOTE: virtual isn't really correct, actually it should be the offset into the + * memory node, but we have no highmem, so that works for now. + * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots + * of the shifts unnecessary. + */ +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) + +#define virt_to_page(kaddr) (mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT)) +#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) + +#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn)) +#define page_to_pfn(page) virt_to_pfn(page_to_virt(page)) + +#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory) +#define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn)) + +#endif /* __ASSEMBLY__ */ + +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#endif /* __KERNEL__ */ + +#endif /* _M68K_PAGE_H */ diff --git a/include/asm-m68k/page_offset.h b/include/asm-m68k/page_offset.h new file mode 100644 index 000000000000..86d3c2845ad4 --- /dev/null +++ b/include/asm-m68k/page_offset.h @@ -0,0 +1,9 @@ +#include <linux/config.h> + +/* This handles the memory map.. */ +#ifndef CONFIG_SUN3 +#define PAGE_OFFSET_RAW 0x00000000 +#else +#define PAGE_OFFSET_RAW 0x0E000000 +#endif + diff --git a/include/asm-m68k/param.h b/include/asm-m68k/param.h new file mode 100644 index 000000000000..60f409d81658 --- /dev/null +++ b/include/asm-m68k/param.h @@ -0,0 +1,22 @@ +#ifndef _M68K_PARAM_H +#define _M68K_PARAM_H + +#ifdef __KERNEL__ +# define HZ 100 /* Internal kernel timer frequency */ +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 8192 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _M68K_PARAM_H */ diff --git a/include/asm-m68k/parport.h b/include/asm-m68k/parport.h new file mode 100644 index 000000000000..646b1872f73b --- /dev/null +++ b/include/asm-m68k/parport.h @@ -0,0 +1,26 @@ +/* + * parport.h: platform-specific PC-style parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk> + * + * This file should only be included by drivers/parport/parport_pc.c. + * + * RZ: for use with Q40 and other ISA machines + */ + +#ifndef _ASM_M68K_PARPORT_H +#define _ASM_M68K_PARPORT_H 1 + +#define insl(port,buf,len) isa_insb(port,buf,(len)<<2) +#define outsl(port,buf,len) isa_outsb(port,buf,(len)<<2) + +/* no dma, or IRQ autoprobing */ +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + if (! (MACH_IS_Q40)) + return 0; /* count=0 */ + return parport_pc_find_isa_ports (PARPORT_IRQ_NONE, PARPORT_DMA_NONE); +} + +#endif /* !(_ASM_M68K_PARPORT_H) */ diff --git a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h new file mode 100644 index 000000000000..9e7d79ab5d13 --- /dev/null +++ b/include/asm-m68k/pci.h @@ -0,0 +1,61 @@ +#ifndef _ASM_M68K_PCI_H +#define _ASM_M68K_PCI_H + +/* + * asm-m68k/pci_m68k.h - m68k specific PCI declarations. + * + * Written by Wout Klaren. + */ + +#include <asm/scatterlist.h> + +struct pci_ops; + +/* + * Structure with hardware dependent information and functions of the + * PCI bus. + */ + +struct pci_bus_info +{ + /* + * Resources of the PCI bus. + */ + + struct resource mem_space; + struct resource io_space; + + /* + * System dependent functions. + */ + + struct pci_ops *m68k_pci_ops; + + void (*fixup)(int pci_modify); + void (*conf_device)(struct pci_dev *dev); +}; + +#define pcibios_assign_all_busses() 0 +#define pcibios_scan_all_fns(a, b) 0 + +static inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + +static inline void pcibios_penalize_isa_irq(int irq) +{ + /* We don't do dynamic PCI IRQ allocation */ +} + +/* The PCI address space does equal the physical memory + * address space. The networking and block device layers use + * this boolean for bounce buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +static inline void pcibios_add_platform_entries(struct pci_dev *dev) +{ +} + +#endif /* _ASM_M68K_PCI_H */ diff --git a/include/asm-m68k/percpu.h b/include/asm-m68k/percpu.h new file mode 100644 index 000000000000..0859d048faf5 --- /dev/null +++ b/include/asm-m68k/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ASM_M68K_PERCPU_H +#define __ASM_M68K_PERCPU_H + +#include <asm-generic/percpu.h> + +#endif /* __ASM_M68K_PERCPU_H */ diff --git a/include/asm-m68k/pgalloc.h b/include/asm-m68k/pgalloc.h new file mode 100644 index 000000000000..b468b7958aaa --- /dev/null +++ b/include/asm-m68k/pgalloc.h @@ -0,0 +1,19 @@ + +#ifndef M68K_PGALLOC_H +#define M68K_PGALLOC_H + +#include <linux/config.h> +#include <linux/mm.h> +#include <linux/highmem.h> +#include <asm/setup.h> +#include <asm/virtconvert.h> + + + +#ifdef CONFIG_SUN3 +#include <asm/sun3_pgalloc.h> +#else +#include <asm/motorola_pgalloc.h> +#endif + +#endif /* M68K_PGALLOC_H */ diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h new file mode 100644 index 000000000000..0eef32778df2 --- /dev/null +++ b/include/asm-m68k/pgtable.h @@ -0,0 +1,191 @@ +#ifndef _M68K_PGTABLE_H +#define _M68K_PGTABLE_H + +#include <asm-generic/4level-fixup.h> + +#include <linux/config.h> +#include <asm/setup.h> + +#ifndef __ASSEMBLY__ +#include <asm/processor.h> +#include <linux/sched.h> +#include <linux/threads.h> + +/* + * This file contains the functions and defines necessary to modify and use + * the m68k page table tree. + */ + +#include <asm/virtconvert.h> + +/* 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); \ + } while(0) +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#ifdef CONFIG_SUN3 +#define PMD_SHIFT 17 +#else +#define PMD_SHIFT 22 +#endif +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#ifdef CONFIG_SUN3 +#define PGDIR_SHIFT 17 +#else +#define PGDIR_SHIFT 25 +#endif +#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. + */ +#ifdef CONFIG_SUN3 +#define PTRS_PER_PTE 16 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 2048 +#else +#define PTRS_PER_PTE 1024 +#define PTRS_PER_PMD 8 +#define PTRS_PER_PGD 128 +#endif +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) +#define FIRST_USER_PGD_NR 0 + +/* Virtual address region for use by kernel_map() */ +#ifdef CONFIG_SUN3 +#define KMAP_START 0x0DC00000 +#define KMAP_END 0x0E000000 +#else +#define KMAP_START 0xd0000000 +#define KMAP_END 0xf0000000 +#endif + +#ifndef CONFIG_SUN3 +/* 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_END KMAP_START +#else +extern unsigned long vmalloc_end; +#define VMALLOC_START 0x0f800000 +#define VMALLOC_END vmalloc_end +#endif /* CONFIG_SUN3 */ + +/* zero page used for uninitialized stuff */ +extern void *empty_zero_page; + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) (virt_to_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 + +/* + * Check if the addr/len goes up to the end of a physical + * memory chunk. Used for DMA functions. + */ +#ifdef CONFIG_SINGLE_MEMORY_CHUNK +/* + * It makes no sense to consider whether we cross a memory boundary if + * we support just one physical chunk of memory. + */ +static inline int mm_end_of_chunk(unsigned long addr, int len) +{ + return 0; +} +#else +int mm_end_of_chunk (unsigned long addr, int len); +#endif + +extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode); + +/* + * The m68k doesn't have any external MMU info: the kernel page + * tables contain all the necessary information. The Sun3 does, but + * they are updated on demand. + */ +static inline void update_mmu_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte) +{ +} + +#endif /* !__ASSEMBLY__ */ + +#define kern_addr_valid(addr) (1) + +#define io_remap_page_range(vma, vaddr, paddr, size, prot) \ + remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) + +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + +/* MMU-specific headers */ + +#ifdef CONFIG_SUN3 +#include <asm/sun3_pgtable.h> +#else +#include <asm/motorola_pgtable.h> +#endif + +#ifndef __ASSEMBLY__ +#include <asm-generic/pgtable.h> + +/* + * Macro to mark a page protection value as "uncacheable". + */ +#ifdef SUN3_PAGE_NOCACHE +# define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE +#else +# define __SUN3_PAGE_NOCACHE 0 +#endif +#define pgprot_noncached(prot) \ + (MMU_IS_SUN3 \ + ? (__pgprot(pgprot_val(prot) | __SUN3_PAGE_NOCACHE)) \ + : ((MMU_IS_851 || MMU_IS_030) \ + ? (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE030)) \ + : (MMU_IS_040 || MMU_IS_060) \ + ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ + : (prot))) + +#endif /* !__ASSEMBLY__ */ + +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + +#define check_pgt_cache() do { } while (0) + +#endif /* _M68K_PGTABLE_H */ diff --git a/include/asm-m68k/poll.h b/include/asm-m68k/poll.h new file mode 100644 index 000000000000..c4b69c4a87e1 --- /dev/null +++ b/include/asm-m68k/poll.h @@ -0,0 +1,23 @@ +#ifndef __m68k_POLL_H +#define __m68k_POLL_H + +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 +#define POLLRDNORM 64 +#define POLLWRNORM POLLOUT +#define POLLRDBAND 128 +#define POLLWRBAND 256 +#define POLLMSG 0x0400 +#define POLLREMOVE 0x1000 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif diff --git a/include/asm-m68k/posix_types.h b/include/asm-m68k/posix_types.h new file mode 100644 index 000000000000..fa166ee30286 --- /dev/null +++ b/include/asm-m68k/posix_types.h @@ -0,0 +1,65 @@ +#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 long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(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 /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h new file mode 100644 index 000000000000..df1575db32af --- /dev/null +++ b/include/asm-m68k/processor.h @@ -0,0 +1,140 @@ +/* + * include/asm-m68k/processor.h + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#ifndef __ASM_M68K_PROCESSOR_H +#define __ASM_M68K_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#include <linux/config.h> +#include <asm/segment.h> +#include <asm/fpu.h> +#include <asm/ptrace.h> + +static inline unsigned long rdusp(void) +{ + unsigned long usp; + + __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); + return usp; +} + +static inline void wrusp(unsigned long usp) +{ + __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); +} + +/* + * 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. + */ +#ifndef CONFIG_SUN3 +#define TASK_SIZE (0xF0000000UL) +#else +#ifdef __ASSEMBLY__ +#define TASK_SIZE (0x0E000000) +#else +#define TASK_SIZE (0x0E000000UL) +#endif +#endif + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#ifndef CONFIG_SUN3 +#define TASK_UNMAPPED_BASE 0xC0000000UL +#else +#define TASK_UNMAPPED_BASE 0x0A000000UL +#endif +#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) + +struct task_work { + unsigned char sigpending; + unsigned char notify_resume; /* request for notification on + userspace execution resumption */ + char need_resched; + unsigned char delayed_trace; /* single step a syscall */ + unsigned char syscall_trace; /* count of syscall interceptors */ + unsigned char memdie; /* task was selected to be killed */ + unsigned char pad[2]; +}; + +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 faddr; /* info about last fault */ + int signo, code; + unsigned long fp[8*3]; + unsigned long fpcntl[3]; /* fp control regs */ + unsigned char fpstate[FPSTATESIZE]; /* floating point state */ + struct task_work work; +}; + +#define INIT_THREAD { \ + ksp: sizeof(init_stack) + (unsigned long) init_stack, \ + sr: PS_S, \ + fs: __KERNEL_DS, \ + info: INIT_THREAD_INFO(init_task) \ +} + +/* + * 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) +{ + /* reads from user space */ + set_fs(USER_DS); + + regs->pc = pc; + regs->sr &= ~0x2000; + wrusp(usp); +} + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +extern unsigned long thread_saved_pc(struct task_struct *tsk); + +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + (virt_addr_valid((tsk)->thread.esp0))) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + +#define cpu_relax() barrier() + +#endif diff --git a/include/asm-m68k/ptrace.h b/include/asm-m68k/ptrace.h new file mode 100644 index 000000000000..57e763d79bf4 --- /dev/null +++ b/include/asm-m68k/ptrace.h @@ -0,0 +1,80 @@ +#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 a2; + 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 a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long retpc; +}; + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 + +#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) +#define profile_pc(regs) instruction_pointer(regs) +extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _M68K_PTRACE_H */ diff --git a/include/asm-m68k/q40_master.h b/include/asm-m68k/q40_master.h new file mode 100644 index 000000000000..3907a09d4fca --- /dev/null +++ b/include/asm-m68k/q40_master.h @@ -0,0 +1,69 @@ +/* + * Q40 master Chip Control + * RTC stuff merged for compactnes.. +*/ + +#ifndef _Q40_MASTER_H +#define _Q40_MASTER_H + +#include <asm/raw_io.h> + + +#define q40_master_addr 0xff000000 + +#define IIRQ_REG 0x0 /* internal IRQ reg */ +#define EIRQ_REG 0x4 /* external ... */ +#define KEYCODE_REG 0x1c /* value of received scancode */ +#define DISPLAY_CONTROL_REG 0x18 +#define FRAME_CLEAR_REG 0x24 +#define LED_REG 0x30 + +#define Q40_LED_ON() master_outb(1,LED_REG) +#define Q40_LED_OFF() master_outb(0,LED_REG) + +#define INTERRUPT_REG IIRQ_REG /* "native" ints */ +#define KEY_IRQ_ENABLE_REG 0x08 /**/ +#define KEYBOARD_UNLOCK_REG 0x20 /* clear kb int */ + +#define SAMPLE_ENABLE_REG 0x14 /* generate SAMPLE ints */ +#define SAMPLE_RATE_REG 0x2c +#define SAMPLE_CLEAR_REG 0x28 +#define SAMPLE_LOW 0x00 +#define SAMPLE_HIGH 0x01 + +#define FRAME_RATE_REG 0x38 /* generate FRAME ints at 200 HZ rate */ + +#if 0 +#define SER_ENABLE_REG 0x0c /* allow serial ints to be generated */ +#endif +#define EXT_ENABLE_REG 0x10 /* ... rest of the ISA ints ... */ + + +#define master_inb(_reg_) in_8((unsigned char *)q40_master_addr+_reg_) +#define master_outb(_b_,_reg_) out_8((unsigned char *)q40_master_addr+_reg_,_b_) + +/* RTC defines */ + +#define Q40_RTC_BASE (0xff021ffc) + +#define Q40_RTC_YEAR (*(volatile unsigned char *)(Q40_RTC_BASE+0)) +#define Q40_RTC_MNTH (*(volatile unsigned char *)(Q40_RTC_BASE-4)) +#define Q40_RTC_DATE (*(volatile unsigned char *)(Q40_RTC_BASE-8)) +#define Q40_RTC_DOW (*(volatile unsigned char *)(Q40_RTC_BASE-12)) +#define Q40_RTC_HOUR (*(volatile unsigned char *)(Q40_RTC_BASE-16)) +#define Q40_RTC_MINS (*(volatile unsigned char *)(Q40_RTC_BASE-20)) +#define Q40_RTC_SECS (*(volatile unsigned char *)(Q40_RTC_BASE-24)) +#define Q40_RTC_CTRL (*(volatile unsigned char *)(Q40_RTC_BASE-28)) + +/* some control bits */ +#define Q40_RTC_READ 64 /* prepare for reading */ +#define Q40_RTC_WRITE 128 + +/* define some Q40 specific ints */ +#include "q40ints.h" + +/* misc defs */ +#define DAC_LEFT ((unsigned char *)0xff008000) +#define DAC_RIGHT ((unsigned char *)0xff008004) + +#endif /* _Q40_MASTER_H */ diff --git a/include/asm-m68k/q40ints.h b/include/asm-m68k/q40ints.h new file mode 100644 index 000000000000..3d970afb708f --- /dev/null +++ b/include/asm-m68k/q40ints.h @@ -0,0 +1,29 @@ +/* + * contains some Q40 related interrupt definitions + */ + +#define Q40_IRQ_MAX (34) + +#define Q40_IRQ_SAMPLE (34) +#define Q40_IRQ_KEYBOARD (32) +#define Q40_IRQ_FRAME (33) + + +/* masks for interrupt regiosters*/ +/* internal, IIRQ_REG */ +#define Q40_IRQ_KEYB_MASK (2) +#define Q40_IRQ_SER_MASK (1<<2) +#define Q40_IRQ_FRAME_MASK (1<<3) +#define Q40_IRQ_EXT_MASK (1<<4) /* is a EIRQ */ +/* eirq, EIRQ_REG */ +#define Q40_IRQ3_MASK (1) +#define Q40_IRQ4_MASK (1<<1) +#define Q40_IRQ5_MASK (1<<2) +#define Q40_IRQ6_MASK (1<<3) +#define Q40_IRQ7_MASK (1<<4) +#define Q40_IRQ10_MASK (1<<5) +#define Q40_IRQ14_MASK (1<<6) +#define Q40_IRQ15_MASK (1<<7) + +extern unsigned long q40_probe_irq_on (void); +extern int q40_probe_irq_off (unsigned long irqs); diff --git a/include/asm-m68k/raw_io.h b/include/asm-m68k/raw_io.h new file mode 100644 index 000000000000..041f0a87b25d --- /dev/null +++ b/include/asm-m68k/raw_io.h @@ -0,0 +1,342 @@ +/* + * linux/include/asm-m68k/raw_io.h + * + * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace + * + */ + +#ifndef _RAW_IO_H +#define _RAW_IO_H + +#ifdef __KERNEL__ + +#include <asm/types.h> + + +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +extern void iounmap(void *addr); + +extern void *__ioremap(unsigned long physaddr, unsigned long size, + int cacheflag); +extern void __iounmap(void *addr, unsigned long size); + + +/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates + * two accesses to memory, which may be undesirable for some devices. + */ +#define in_8(addr) \ + ({ u8 __v = (*(volatile u8 *) (addr)); __v; }) +#define in_be16(addr) \ + ({ u16 __v = (*(volatile u16 *) (addr)); __v; }) +#define in_be32(addr) \ + ({ u32 __v = (*(volatile u32 *) (addr)); __v; }) +#define in_le16(addr) \ + ({ u16 __v = le16_to_cpu(*(volatile u16 *) (addr)); __v; }) +#define in_le32(addr) \ + ({ u32 __v = le32_to_cpu(*(volatile u32 *) (addr)); __v; }) + +#define out_8(addr,b) (void)((*(volatile u8 *) (addr)) = (b)) +#define out_be16(addr,w) (void)((*(volatile u16 *) (addr)) = (w)) +#define out_be32(addr,l) (void)((*(volatile u32 *) (addr)) = (l)) +#define out_le16(addr,w) (void)((*(volatile u16 *) (addr)) = cpu_to_le16(w)) +#define out_le32(addr,l) (void)((*(volatile u32 *) (addr)) = cpu_to_le32(l)) + +#define raw_inb in_8 +#define raw_inw in_be16 +#define raw_inl in_be32 + +#define raw_outb(val,port) out_8((port),(val)) +#define raw_outw(val,port) out_be16((port),(val)) +#define raw_outl(val,port) out_be32((port),(val)) + +static inline void raw_insb(volatile u8 *port, u8 *buf, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + *buf++ = in_8(port); +} + +static inline void raw_outsb(volatile u8 *port, const u8 *buf, + unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + out_8(port, *buf++); +} + +static inline void raw_insw(volatile u16 *port, u16 *buf, unsigned int nr) +{ + unsigned int tmp; + + if (nr & 15) { + tmp = (nr & 15) - 1; + asm volatile ( + "1: movew %2@,%0@+; dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } + if (nr >> 4) { + tmp = (nr >> 4) - 1; + asm volatile ( + "1: " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } +} + +static inline void raw_outsw(volatile u16 *port, const u16 *buf, + unsigned int nr) +{ + unsigned int tmp; + + if (nr & 15) { + tmp = (nr & 15) - 1; + asm volatile ( + "1: movew %0@+,%2@; dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } + if (nr >> 4) { + tmp = (nr >> 4) - 1; + asm volatile ( + "1: " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } +} + +static inline void raw_insl(volatile u32 *port, u32 *buf, unsigned int nr) +{ + unsigned int tmp; + + if (nr & 15) { + tmp = (nr & 15) - 1; + asm volatile ( + "1: movel %2@,%0@+; dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } + if (nr >> 4) { + tmp = (nr >> 4) - 1; + asm volatile ( + "1: " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } +} + +static inline void raw_outsl(volatile u32 *port, const u32 *buf, + unsigned int nr) +{ + unsigned int tmp; + + if (nr & 15) { + tmp = (nr & 15) - 1; + asm volatile ( + "1: movel %0@+,%2@; dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } + if (nr >> 4) { + tmp = (nr >> 4) - 1; + asm volatile ( + "1: " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } +} + + +static inline void raw_insw_swapw(volatile u16 *port, u16 *buf, + unsigned int nr) +{ + if ((nr) % 8) + __asm__ __volatile__ + ("\tmovel %0,%/a0\n\t" + "movel %1,%/a1\n\t" + "movel %2,%/d6\n\t" + "subql #1,%/d6\n" + "1:\tmovew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "dbra %/d6,1b" + : + : "g" (port), "g" (buf), "g" (nr) + : "d0", "a0", "a1", "d6"); + else + __asm__ __volatile__ + ("movel %0,%/a0\n\t" + "movel %1,%/a1\n\t" + "movel %2,%/d6\n\t" + "lsrl #3,%/d6\n\t" + "subql #1,%/d6\n" + "1:\tmovew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "dbra %/d6,1b" + : + : "g" (port), "g" (buf), "g" (nr) + : "d0", "a0", "a1", "d6"); +} + +static inline void raw_outsw_swapw(volatile u16 *port, const u16 *buf, + unsigned int nr) +{ + if ((nr) % 8) + __asm__ __volatile__ + ("movel %0,%/a0\n\t" + "movel %1,%/a1\n\t" + "movel %2,%/d6\n\t" + "subql #1,%/d6\n" + "1:\tmovew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "dbra %/d6,1b" + : + : "g" (port), "g" (buf), "g" (nr) + : "d0", "a0", "a1", "d6"); + else + __asm__ __volatile__ + ("movel %0,%/a0\n\t" + "movel %1,%/a1\n\t" + "movel %2,%/d6\n\t" + "lsrl #3,%/d6\n\t" + "subql #1,%/d6\n" + "1:\tmovew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "dbra %/d6,1b" + : + : "g" (port), "g" (buf), "g" (nr) + : "d0", "a0", "a1", "d6"); +} + + +#endif /* __KERNEL__ */ + +#endif /* _RAW_IO_H */ diff --git a/include/asm-m68k/resource.h b/include/asm-m68k/resource.h new file mode 100644 index 000000000000..e7d35019f337 --- /dev/null +++ b/include/asm-m68k/resource.h @@ -0,0 +1,6 @@ +#ifndef _M68K_RESOURCE_H +#define _M68K_RESOURCE_H + +#include <asm-generic/resource.h> + +#endif /* _M68K_RESOURCE_H */ diff --git a/include/asm-m68k/rtc.h b/include/asm-m68k/rtc.h new file mode 100644 index 000000000000..71406fc4e599 --- /dev/null +++ b/include/asm-m68k/rtc.h @@ -0,0 +1,76 @@ +/* asm-m68k/rtc.h + * + * Copyright Richard Zidlicky + * implementation details for genrtc/q40rtc driver + */ +/* permission is hereby granted to copy, modify and redistribute this code + * in terms of the GNU Library General Public License, Version 2 or later, + * at your option. + */ + +#ifndef _ASM_RTC_H +#define _ASM_RTC_H + +#ifdef __KERNEL__ + +#include <linux/rtc.h> +#include <asm/errno.h> +#include <asm/machdep.h> + +#define RTC_PIE 0x40 /* periodic interrupt enable */ +#define RTC_AIE 0x20 /* alarm interrupt enable */ +#define RTC_UIE 0x10 /* update-finished interrupt enable */ + +/* some dummy definitions */ +#define RTC_BATT_BAD 0x100 /* battery bad */ +#define RTC_SQWE 0x08 /* enable square-wave output */ +#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ +#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ +#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ + +static inline unsigned int get_rtc_time(struct rtc_time *time) +{ + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + mach_hwclk(0, time); + return RTC_24H; +} + +static inline int set_rtc_time(struct rtc_time *time) +{ + return mach_hwclk(1, time); +} + +static inline unsigned int get_rtc_ss(void) +{ + if (mach_get_ss) + return mach_get_ss(); + else{ + struct rtc_time h; + + get_rtc_time(&h); + return h.tm_sec; + } +} + +static inline int get_rtc_pll(struct rtc_pll_info *pll) +{ + if (mach_get_rtc_pll) + return mach_get_rtc_pll(pll); + else + return -EINVAL; +} +static inline int set_rtc_pll(struct rtc_pll_info *pll) +{ + if (mach_set_rtc_pll) + return mach_set_rtc_pll(pll); + else + return -EINVAL; +} +#endif /* __KERNEL__ */ + +#endif /* _ASM__RTC_H */ diff --git a/include/asm-m68k/sbus.h b/include/asm-m68k/sbus.h new file mode 100644 index 000000000000..3b25c0040aa6 --- /dev/null +++ b/include/asm-m68k/sbus.h @@ -0,0 +1,50 @@ +/* + * some sbus structures and macros to make usage of sbus drivers possible + */ + +#ifndef __M68K_SBUS_H +#define __M68K_SBUS_H + +struct sbus_dev { + struct { + unsigned int which_io; + unsigned int phys_addr; + } reg_addrs[1]; +}; + +extern void *sparc_alloc_io (u32, void *, int, char *, u32, int); +#define sparc_alloc_io(a,b,c,d,e,f) (a) + +#define ARCH_SUN4 0 + +/* sbus IO functions stolen from include/asm-sparc/io.h for the serial driver */ +/* No SBUS on the Sun3, kludge -- sam */ + +static inline void _sbus_writeb(unsigned char val, unsigned long addr) +{ + *(volatile unsigned char *)addr = val; +} + +static inline unsigned char _sbus_readb(unsigned long addr) +{ + return *(volatile unsigned char *)addr; +} + +static inline void _sbus_writel(unsigned long val, unsigned long addr) +{ + *(volatile unsigned long *)addr = val; + +} + +extern inline unsigned long _sbus_readl(unsigned long addr) +{ + return *(volatile unsigned long *)addr; +} + + +#define sbus_readb(a) _sbus_readb((unsigned long)a) +#define sbus_writeb(v, a) _sbus_writeb(v, (unsigned long)a) +#define sbus_readl(a) _sbus_readl((unsigned long)a) +#define sbus_writel(v, a) _sbus_writel(v, (unsigned long)a) + +#endif diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h new file mode 100644 index 000000000000..d7c9b5c5e6c7 --- /dev/null +++ b/include/asm-m68k/scatterlist.h @@ -0,0 +1,19 @@ +#ifndef _M68K_SCATTERLIST_H +#define _M68K_SCATTERLIST_H + +struct scatterlist { + /* These two are only valid if ADDRESS member of this + * struct is NULL. + */ + struct page *page; + unsigned int offset; + + unsigned int length; + + __u32 dvma_address; /* A place to hang host-specific addresses at. */ +}; + +/* This is bogus and should go away. */ +#define ISA_DMA_THRESHOLD (0x00ffffff) + +#endif /* !(_M68K_SCATTERLIST_H) */ diff --git a/include/asm-m68k/sections.h b/include/asm-m68k/sections.h new file mode 100644 index 000000000000..d64967ecfec6 --- /dev/null +++ b/include/asm-m68k/sections.h @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_SECTIONS_H +#define _ASM_M68K_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif /* _ASM_M68K_SECTIONS_H */ diff --git a/include/asm-m68k/segment.h b/include/asm-m68k/segment.h new file mode 100644 index 000000000000..7b0b2d3127f9 --- /dev/null +++ b/include/asm-m68k/segment.h @@ -0,0 +1,57 @@ +#ifndef _M68K_SEGMENT_H +#define _M68K_SEGMENT_H + +/* define constants */ +/* Address spaces (FC0-FC2) */ +#define USER_DATA (1) +#ifndef __USER_DS +#define __USER_DS (USER_DATA) +#endif +#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) + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned long seg; +} mm_segment_t; + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) +#define USER_DS MAKE_MM_SEG(__USER_DS) +#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) + +/* + * Get/set the SFC/DFC registers for MOVES instructions + */ + +static inline mm_segment_t get_fs(void) +{ + mm_segment_t _v; + __asm__ ("movec %/dfc,%0":"=r" (_v.seg):); + + return _v; +} + +static inline mm_segment_t get_ds(void) +{ + /* return the supervisor data space code */ + return KERNEL_DS; +} + +static inline void set_fs(mm_segment_t val) +{ + __asm__ __volatile__ ("movec %0,%/sfc\n\t" + "movec %0,%/dfc\n\t" + : /* no outputs */ : "r" (val.seg) : "memory"); +} + +#define segment_eq(a,b) ((a).seg == (b).seg) + +#endif /* __ASSEMBLY__ */ + +#endif /* _M68K_SEGMENT_H */ diff --git a/include/asm-m68k/semaphore-helper.h b/include/asm-m68k/semaphore-helper.h new file mode 100644 index 000000000000..1516a642f9a5 --- /dev/null +++ b/include/asm-m68k/semaphore-helper.h @@ -0,0 +1,143 @@ +#ifndef _M68K_SEMAPHORE_HELPER_H +#define _M68K_SEMAPHORE_HELPER_H + +/* + * SMP- and interrupt-safe semaphores helper functions. + * + * (C) Copyright 1996 Linus Torvalds + * + * m68k version by Andreas Schwab + */ + +#include <linux/config.h> +#include <linux/errno.h> + +/* + * These two _must_ execute atomically wrt each other. + */ +static inline void wake_one_more(struct semaphore * sem) +{ + atomic_inc(&sem->waking); +} + +#ifndef CONFIG_RMW_INSNS +extern spinlock_t semaphore_wake_lock; +#endif + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret; +#ifndef CONFIG_RMW_INSNS + unsigned long flags; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + ret = 0; + if (atomic_read(&sem->waking) > 0) { + atomic_dec(&sem->waking); + ret = 1; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); +#else + int tmp1, tmp2; + + __asm__ __volatile__ + ("1: movel %1,%2\n" + " jle 2f\n" + " subql #1,%2\n" + " casl %1,%2,%3\n" + " jne 1b\n" + " moveq #1,%0\n" + "2:" + : "=d" (ret), "=d" (tmp1), "=d" (tmp2) + : "m" (sem->waking), "0" (0), "1" (sem->waking)); +#endif + + return ret; +} + +/* + * waking_non_zero_interruptible: + * 1 got the lock + * 0 go to sleep + * -EINTR interrupted + */ +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) +{ + int ret; +#ifndef CONFIG_RMW_INSNS + unsigned long flags; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + ret = 0; + if (atomic_read(&sem->waking) > 0) { + atomic_dec(&sem->waking); + ret = 1; + } else if (signal_pending(tsk)) { + atomic_inc(&sem->count); + ret = -EINTR; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); +#else + int tmp1, tmp2; + + __asm__ __volatile__ + ("1: movel %1,%2\n" + " jle 2f\n" + " subql #1,%2\n" + " casl %1,%2,%3\n" + " jne 1b\n" + " moveq #1,%0\n" + " jra %a4\n" + "2:" + : "=d" (ret), "=d" (tmp1), "=d" (tmp2) + : "m" (sem->waking), "i" (&&next), "0" (0), "1" (sem->waking)); + if (signal_pending(tsk)) { + atomic_inc(&sem->count); + ret = -EINTR; + } +next: +#endif + + return ret; +} + +/* + * waking_non_zero_trylock: + * 1 failed to lock + * 0 got the lock + */ +static inline int waking_non_zero_trylock(struct semaphore *sem) +{ + int ret; +#ifndef CONFIG_RMW_INSNS + unsigned long flags; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + ret = 1; + if (atomic_read(&sem->waking) > 0) { + atomic_dec(&sem->waking); + ret = 0; + } else + atomic_inc(&sem->count); + spin_unlock_irqrestore(&semaphore_wake_lock, flags); +#else + int tmp1, tmp2; + + __asm__ __volatile__ + ("1: movel %1,%2\n" + " jle 2f\n" + " subql #1,%2\n" + " casl %1,%2,%3\n" + " jne 1b\n" + " moveq #0,%0\n" + "2:" + : "=d" (ret), "=d" (tmp1), "=d" (tmp2) + : "m" (sem->waking), "0" (1), "1" (sem->waking)); + if (ret) + atomic_inc(&sem->count); +#endif + return ret; +} + +#endif diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h new file mode 100644 index 000000000000..ab94cf3ed447 --- /dev/null +++ b/include/asm-m68k/semaphore.h @@ -0,0 +1,167 @@ +#ifndef _M68K_SEMAPHORE_H +#define _M68K_SEMAPHORE_H + +#define RW_LOCK_BIAS 0x01000000 + +#ifndef __ASSEMBLY__ + +#include <linux/linkage.h> +#include <linux/wait.h> +#include <linux/spinlock.h> +#include <linux/rwsem.h> +#include <linux/stringify.h> + +#include <asm/system.h> +#include <asm/atomic.h> + +/* + * Interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + * + * m68k version by Andreas Schwab + */ + + +struct semaphore { + atomic_t count; + atomic_t waking; + wait_queue_head_t wait; +}; + +#define __SEMAPHORE_INITIALIZER(name, n) \ +{ \ + .count = ATOMIC_INIT(n), \ + .waking = ATOMIC_INIT(0), \ + .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ +} + +#define __MUTEX_INITIALIZER(name) \ + __SEMAPHORE_INITIALIZER(name,1) + +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) + +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) + +static inline void sema_init(struct semaphore *sem, int val) +{ + *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); +} + +static inline void init_MUTEX (struct semaphore *sem) +{ + sema_init(sem, 1); +} + +static inline void init_MUTEX_LOCKED (struct semaphore *sem) +{ + sema_init(sem, 0); +} + +asmlinkage void __down_failed(void /* special register calling convention */); +asmlinkage int __down_failed_interruptible(void /* params in registers */); +asmlinkage int __down_failed_trylock(void /* params in registers */); +asmlinkage void __up_wakeup(void /* special register calling convention */); + +asmlinkage void __down(struct semaphore * sem); +asmlinkage int __down_interruptible(struct semaphore * sem); +asmlinkage int __down_trylock(struct semaphore * sem); +asmlinkage 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 + */ +static inline void down(struct semaphore *sem) +{ + register struct semaphore *sem1 __asm__ ("%a1") = sem; + + might_sleep(); + __asm__ __volatile__( + "| atomic down operation\n\t" + "subql #1,%0@\n\t" + "jmi 2f\n\t" + "1:\n" + LOCK_SECTION_START(".even\n\t") + "2:\tpea 1b\n\t" + "jbra __down_failed\n" + LOCK_SECTION_END + : /* no outputs */ + : "a" (sem1) + : "memory"); +} + +static inline int down_interruptible(struct semaphore *sem) +{ + register struct semaphore *sem1 __asm__ ("%a1") = sem; + register int result __asm__ ("%d0"); + + might_sleep(); + __asm__ __volatile__( + "| atomic interruptible down operation\n\t" + "subql #1,%1@\n\t" + "jmi 2f\n\t" + "clrl %0\n" + "1:\n" + LOCK_SECTION_START(".even\n\t") + "2:\tpea 1b\n\t" + "jbra __down_failed_interruptible\n" + LOCK_SECTION_END + : "=d" (result) + : "a" (sem1) + : "memory"); + return result; +} + +static inline int down_trylock(struct semaphore *sem) +{ + register struct semaphore *sem1 __asm__ ("%a1") = sem; + register int result __asm__ ("%d0"); + + __asm__ __volatile__( + "| atomic down trylock operation\n\t" + "subql #1,%1@\n\t" + "jmi 2f\n\t" + "clrl %0\n" + "1:\n" + LOCK_SECTION_START(".even\n\t") + "2:\tpea 1b\n\t" + "jbra __down_failed_trylock\n" + LOCK_SECTION_END + : "=d" (result) + : "a" (sem1) + : "memory"); + return result; +} + +/* + * 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(). + */ +static inline void up(struct semaphore *sem) +{ + register struct semaphore *sem1 __asm__ ("%a1") = sem; + + __asm__ __volatile__( + "| atomic up operation\n\t" + "addql #1,%0@\n\t" + "jle 2f\n" + "1:\n" + LOCK_SECTION_START(".even\n\t") + "2:\t" + "pea 1b\n\t" + "jbra __up_wakeup\n" + LOCK_SECTION_END + : /* no outputs */ + : "a" (sem1) + : "memory"); +} + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/include/asm-m68k/sembuf.h b/include/asm-m68k/sembuf.h new file mode 100644 index 000000000000..2308052a8c24 --- /dev/null +++ b/include/asm-m68k/sembuf.h @@ -0,0 +1,25 @@ +#ifndef _M68K_SEMBUF_H +#define _M68K_SEMBUF_H + +/* + * The semid64_ds structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _M68K_SEMBUF_H */ diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h new file mode 100644 index 000000000000..9f5bcdc105fc --- /dev/null +++ b/include/asm-m68k/serial.h @@ -0,0 +1,79 @@ +/* + * include/asm-m68k/serial.h + * + * currently this seems useful only for a Q40, + * it's an almost exact copy of ../asm-alpha/serial.h + * + */ + +#include <linux/config.h> + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD ( 1843200 / 16 ) + +/* Standard COM flags (except for COM4, because of the 8514 problem) */ +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF +#endif + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define FOURPORT_FLAGS ASYNC_FOURPORT +#define ACCENT_FLAGS 0 +#define BOCA_FLAGS 0 +#endif + +#define STD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ + + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define EXTRA_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ + { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ + { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ + { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ + { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ + { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ + { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ + { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ + { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ + { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ + { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ + { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ + { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ + { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ + { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ + { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ + { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ + { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ + { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ + { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ + { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ + { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ + { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ + { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ + { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ + { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ + { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ + { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ +#else +#define EXTRA_SERIAL_PORT_DEFNS +#endif + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DEFNS \ + EXTRA_SERIAL_PORT_DEFNS diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h new file mode 100644 index 000000000000..9e23492685eb --- /dev/null +++ b/include/asm-m68k/setup.h @@ -0,0 +1,375 @@ +/* +** asm/setup.h -- Definition of the Linux/m68k setup information +** +** 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. +** 5/10/96 Geert Uytterhoeven: +** Redesign of the boot information structure; moved boot information +** structure to bootinfo.h +*/ + +#ifndef _M68K_SETUP_H +#define _M68K_SETUP_H + +#include <linux/config.h> + + + /* + * Linux/m68k Architectures + */ + +#define MACH_AMIGA 1 +#define MACH_ATARI 2 +#define MACH_MAC 3 +#define MACH_APOLLO 4 +#define MACH_SUN3 5 +#define MACH_MVME147 6 +#define MACH_MVME16x 7 +#define MACH_BVME6000 8 +#define MACH_HP300 9 +#define MACH_Q40 10 +#define MACH_SUN3X 11 + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +extern unsigned long m68k_machtype; +#endif /* !__ASSEMBLY__ */ + +#if !defined(CONFIG_AMIGA) +# define MACH_IS_AMIGA (0) +#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ + || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA) +#else +# define MACH_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) || defined(CONFIG_APOLLO) \ + || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI) +#else +# define MACH_ATARI_ONLY +# define MACH_IS_ATARI (1) +# define MACH_TYPE (MACH_ATARI) +#endif + +#if !defined(CONFIG_MAC) +# define MACH_IS_MAC (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \ + || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_MAC (m68k_machtype == MACH_MAC) +#else +# define MACH_MAC_ONLY +# define MACH_IS_MAC (1) +# define MACH_TYPE (MACH_MAC) +#endif + +#if defined(CONFIG_SUN3) +#define MACH_IS_SUN3 (1) +#define MACH_SUN3_ONLY (1) +#define MACH_TYPE (MACH_SUN3) +#else +#define MACH_IS_SUN3 (0) +#endif + +#if !defined (CONFIG_APOLLO) +# define MACH_IS_APOLLO (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO) +#else +# define MACH_APOLLO_ONLY +# define MACH_IS_APOLLO (1) +# define MACH_TYPE (MACH_APOLLO) +#endif + +#if !defined (CONFIG_MVME147) +# define MACH_IS_MVME147 (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x) +# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147) +#else +# define MACH_MVME147_ONLY +# define MACH_IS_MVME147 (1) +# define MACH_TYPE (MACH_MVME147) +#endif + +#if !defined (CONFIG_MVME16x) +# define MACH_IS_MVME16x (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x) +#else +# define MACH_MVME16x_ONLY +# define MACH_IS_MVME16x (1) +# define MACH_TYPE (MACH_MVME16x) +#endif + +#if !defined (CONFIG_BVME6000) +# define MACH_IS_BVME6000 (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000) +#else +# define MACH_BVME6000_ONLY +# define MACH_IS_BVME6000 (1) +# define MACH_TYPE (MACH_BVME6000) +#endif + +#if !defined (CONFIG_HP300) +# define MACH_IS_HP300 (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ + || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_HP300 (m68k_machtype == MACH_HP300) +#else +# define MACH_HP300_ONLY +# define MACH_IS_HP300 (1) +# define MACH_TYPE (MACH_HP300) +#endif + +#if !defined (CONFIG_Q40) +# define MACH_IS_Q40 (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ + || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_Q40 (m68k_machtype == MACH_Q40) +#else +# define MACH_Q40_ONLY +# define MACH_IS_Q40 (1) +# define MACH_TYPE (MACH_Q40) +#endif + +#if !defined (CONFIG_SUN3X) +# define MACH_IS_SUN3X (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ + || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ + || defined(CONFIG_Q40) || defined(CONFIG_MVME147) +# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X) +#else +# define CONFIG_SUN3X_ONLY +# define MACH_IS_SUN3X (1) +# define MACH_TYPE (MACH_SUN3X) +#endif + +#ifndef MACH_TYPE +# define MACH_TYPE (m68k_machtype) +#endif + +#endif /* __KERNEL__ */ + + + /* + * CPU, FPU and MMU types + * + * Note: we may rely on the following equalities: + * + * CPU_68020 == MMU_68851 + * CPU_68030 == MMU_68030 + * CPU_68040 == FPU_68040 == MMU_68040 + * CPU_68060 == FPU_68060 == MMU_68060 + */ + +#define CPUB_68020 0 +#define CPUB_68030 1 +#define CPUB_68040 2 +#define CPUB_68060 3 + +#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 FPUB_68881 0 +#define FPUB_68882 1 +#define FPUB_68040 2 /* Internal FPU */ +#define FPUB_68060 3 /* Internal FPU */ +#define FPUB_SUNFPA 4 /* Sun-3 FPA */ + +#define FPU_68881 (1<<FPUB_68881) +#define FPU_68882 (1<<FPUB_68882) +#define FPU_68040 (1<<FPUB_68040) +#define FPU_68060 (1<<FPUB_68060) +#define FPU_SUNFPA (1<<FPUB_SUNFPA) + +#define MMUB_68851 0 +#define MMUB_68030 1 /* Internal MMU */ +#define MMUB_68040 2 /* Internal MMU */ +#define MMUB_68060 3 /* Internal MMU */ +#define MMUB_APOLLO 4 /* Custom Apollo */ +#define MMUB_SUN3 5 /* Custom Sun-3 */ + +#define MMU_68851 (1<<MMUB_68851) +#define MMU_68030 (1<<MMUB_68030) +#define MMU_68040 (1<<MMUB_68040) +#define MMU_68060 (1<<MMUB_68060) +#define MMU_SUN3 (1<<MMUB_SUN3) +#define MMU_APOLLO (1<<MMUB_APOLLO) + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +extern unsigned long m68k_cputype; +extern unsigned long m68k_fputype; +extern unsigned long m68k_mmutype; /* Not really used yet */ +#ifdef CONFIG_VME +extern unsigned long vme_brdtype; +#endif + + /* + * m68k_is040or060 is != 0 for a '040 or higher; + * used numbers are 4 for 68040 and 6 for 68060. + */ + +extern int m68k_is040or060; +#endif /* !__ASSEMBLY__ */ + +#if !defined(CONFIG_M68020) +# define CPU_IS_020 (0) +# define MMU_IS_851 (0) +# define MMU_IS_SUN3 (0) +#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_020 (m68k_cputype & CPU_68020) +# define MMU_IS_851 (m68k_mmutype & MMU_68851) +# define MMU_IS_SUN3 (0) /* Sun3 not supported with other CPU enabled */ +#else +# define CPU_M68020_ONLY +# define CPU_IS_020 (1) +#ifdef MACH_SUN3_ONLY +# define MMU_IS_SUN3 (1) +# define MMU_IS_851 (0) +#else +# define MMU_IS_SUN3 (0) +# define MMU_IS_851 (1) +#endif +#endif + +#if !defined(CONFIG_M68030) +# define CPU_IS_030 (0) +# define MMU_IS_030 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_030 (m68k_cputype & CPU_68030) +# define MMU_IS_030 (m68k_mmutype & MMU_68030) +#else +# define CPU_M68030_ONLY +# define CPU_IS_030 (1) +# define MMU_IS_030 (1) +#endif + +#if !defined(CONFIG_M68040) +# define CPU_IS_040 (0) +# define MMU_IS_040 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060) +# define CPU_IS_040 (m68k_cputype & CPU_68040) +# define MMU_IS_040 (m68k_mmutype & MMU_68040) +#else +# define CPU_M68040_ONLY +# define CPU_IS_040 (1) +# define MMU_IS_040 (1) +#endif + +#if !defined(CONFIG_M68060) +# define CPU_IS_060 (0) +# define MMU_IS_060 (0) +#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040) +# define CPU_IS_060 (m68k_cputype & CPU_68060) +# define MMU_IS_060 (m68k_mmutype & MMU_68060) +#else +# define CPU_M68060_ONLY +# define CPU_IS_060 (1) +# define MMU_IS_060 (1) +#endif + +#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030) +# define CPU_IS_020_OR_030 (0) +#else +# define CPU_M68020_OR_M68030 +# if defined(CONFIG_M68040) || defined(CONFIG_M68060) +# define CPU_IS_020_OR_030 (!m68k_is040or060) +# else +# define CPU_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 CPU_M68040_OR_M68060 +# if defined(CONFIG_M68020) || defined(CONFIG_M68030) +# define CPU_IS_040_OR_060 (m68k_is040or060) +# else +# define CPU_M68040_OR_M68060_ONLY +# define CPU_IS_040_OR_060 (1) +# endif +#endif + +#define CPU_TYPE (m68k_cputype) + +#ifdef CONFIG_M68KFPU_EMU +# ifdef CONFIG_M68KFPU_EMU_ONLY +# define FPU_IS_EMU (1) +# else +# define FPU_IS_EMU (!m68k_fputype) +# endif +#else +# define FPU_IS_EMU (0) +#endif + + + /* + * Miscellaneous + */ + +#define NUM_MEMINFO 4 +#define CL_SIZE 256 +#define COMMAND_LINE_SIZE CL_SIZE + +#ifndef __ASSEMBLY__ +extern int m68k_num_memory; /* # of memory blocks found (and used) */ +extern int m68k_realnum_memory; /* real # of memory blocks found */ +extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */ + +struct mem_info { + unsigned long addr; /* physical address of memory chunk */ + unsigned long size; /* length of memory chunk (in bytes) */ +}; +#endif + +#endif /* __KERNEL__ */ + +#endif /* _M68K_SETUP_H */ diff --git a/include/asm-m68k/shm.h b/include/asm-m68k/shm.h new file mode 100644 index 000000000000..3fa2f368fc1a --- /dev/null +++ b/include/asm-m68k/shm.h @@ -0,0 +1,32 @@ +#ifndef _M68K_SHM_H +#define _M68K_SHM_H + +#include <linux/config.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 */ +/* format on the sun3 is similar, but bits 30, 31 are set to zero and all + others are reduced by 2. --m */ + +#ifndef CONFIG_SUN3 +#define SHM_ID_SHIFT 9 +#else +#define SHM_ID_SHIFT 7 +#endif +#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/shmbuf.h b/include/asm-m68k/shmbuf.h new file mode 100644 index 000000000000..f8928d62f1b7 --- /dev/null +++ b/include/asm-m68k/shmbuf.h @@ -0,0 +1,42 @@ +#ifndef _M68K_SHMBUF_H +#define _M68K_SHMBUF_H + +/* + * The shmid64_ds structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _M68K_SHMBUF_H */ diff --git a/include/asm-m68k/shmparam.h b/include/asm-m68k/shmparam.h new file mode 100644 index 000000000000..558892a2efb3 --- /dev/null +++ b/include/asm-m68k/shmparam.h @@ -0,0 +1,6 @@ +#ifndef _M68K_SHMPARAM_H +#define _M68K_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _M68K_SHMPARAM_H */ diff --git a/include/asm-m68k/sigcontext.h b/include/asm-m68k/sigcontext.h new file mode 100644 index 000000000000..64fbe34cf26f --- /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/siginfo.h b/include/asm-m68k/siginfo.h new file mode 100644 index 000000000000..05a8d6d90b58 --- /dev/null +++ b/include/asm-m68k/siginfo.h @@ -0,0 +1,92 @@ +#ifndef _M68K_SIGINFO_H +#define _M68K_SIGINFO_H + +#define HAVE_ARCH_SIGINFO_T +#define HAVE_ARCH_COPY_SIGINFO + +#include <asm-generic/siginfo.h> + +typedef struct siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[SI_PAD_SIZE]; + + /* kill() */ + struct { + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ + __kernel_uid32_t _uid32; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; + sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; + + /* POSIX.1b signals */ + struct { + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ + sigval_t _sigval; + __kernel_uid32_t _uid32; /* sender's uid */ + } _rt; + + /* SIGCHLD */ + struct { + __kernel_pid_t _pid; /* which child */ + __kernel_uid_t _uid; /* backwards compatibility */ + int _status; /* exit code */ + clock_t _utime; + clock_t _stime; + __kernel_uid32_t _uid32; /* sender's uid */ + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + void *_addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} siginfo_t; + +#define UID16_SIGINFO_COMPAT_NEEDED + +/* + * How these fields are to be accessed. + */ +#undef si_uid +#ifdef __KERNEL__ +#define si_uid _sifields._kill._uid32 +#define si_uid16 _sifields._kill._uid +#else +#define si_uid _sifields._kill._uid +#endif + +#ifdef __KERNEL__ + +#include <linux/string.h> + +static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) +{ + if (from->si_code < 0) + memcpy(to, from, sizeof(*to)); + else + /* _sigchld is currently the largest know union member */ + memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h new file mode 100644 index 000000000000..6681bb6a5523 --- /dev/null +++ b/include/asm-m68k/signal.h @@ -0,0 +1,220 @@ +#ifndef _M68K_SIGNAL_H +#define _M68K_SIGNAL_H + +#include <linux/types.h> + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#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 SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * 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_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND +#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#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. + * SA_SHIRQ is for shared interrupt support on PCI and EISA. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_SHIRQ 0x04000000 +#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 */ + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +#include <asm/sigcontext.h> + +#define __HAVE_ARCH_SIG_BITOPS + +static inline void sigaddset(sigset_t *set, int _sig) +{ + __asm__("bfset %0{%1,#1}" : "=m" (*set) : "id" ((_sig - 1) ^ 31) + : "cc"); +} + +static inline void sigdelset(sigset_t *set, int _sig) +{ + __asm__("bfclr %0{%1,#1}" : "=m"(*set) : "id"((_sig - 1) ^ 31) + : "cc"); +} + +static inline int __const_sigismember(sigset_t *set, int _sig) +{ + unsigned long sig = _sig - 1; + return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); +} + +static inline int __gen_sigismember(sigset_t *set, int _sig) +{ + int ret; + __asm__("bfextu %1{%2,#1},%0" + : "=d"(ret) : "m"(*set), "id"((_sig-1) ^ 31)); + return ret; +} + +#define sigismember(set,sig) \ + (__builtin_constant_p(sig) ? \ + __const_sigismember(set,sig) : \ + __gen_sigismember(set,sig)) + +static inline int sigfindinword(unsigned long word) +{ + __asm__("bfffo %1{#0,#0},%0" : "=d"(word) : "d"(word & -word) : "cc"); + return word ^ 31; +} + +extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); + +#endif /* __KERNEL__ */ + +#endif /* _M68K_SIGNAL_H */ diff --git a/include/asm-m68k/socket.h b/include/asm-m68k/socket.h new file mode 100644 index 000000000000..8d0b9fc2d07e --- /dev/null +++ b/include/asm-m68k/socket.h @@ -0,0 +1,50 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockopt(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 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 + +#define SO_PEERSEC 31 + +#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-m68k/sockios.h b/include/asm-m68k/sockios.h new file mode 100644 index 000000000000..9b9ed973c24e --- /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/spinlock.h b/include/asm-m68k/spinlock.h new file mode 100644 index 000000000000..20f46e27b534 --- /dev/null +++ b/include/asm-m68k/spinlock.h @@ -0,0 +1,6 @@ +#ifndef __M68K_SPINLOCK_H +#define __M68K_SPINLOCK_H + +#error "m68k doesn't do SMP yet" + +#endif diff --git a/include/asm-m68k/stat.h b/include/asm-m68k/stat.h new file mode 100644 index 000000000000..c4c402a45e21 --- /dev/null +++ b/include/asm-m68k/stat.h @@ -0,0 +1,78 @@ +#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; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned long long st_dev; + unsigned char __pad1[2]; + +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[2]; + + long long st_size; + unsigned long st_blksize; + + unsigned long __pad4; /* future possible st_blocks high bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned long st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; + + unsigned long long st_ino; +}; + +#endif /* _M68K_STAT_H */ diff --git a/include/asm-m68k/statfs.h b/include/asm-m68k/statfs.h new file mode 100644 index 000000000000..08d93f14e061 --- /dev/null +++ b/include/asm-m68k/statfs.h @@ -0,0 +1,6 @@ +#ifndef _M68K_STATFS_H +#define _M68K_STATFS_H + +#include <asm-generic/statfs.h> + +#endif /* _M68K_STATFS_H */ diff --git a/include/asm-m68k/string.h b/include/asm-m68k/string.h new file mode 100644 index 000000000000..44def078132a --- /dev/null +++ b/include/asm-m68k/string.h @@ -0,0 +1,542 @@ +#ifndef _M68K_STRING_H_ +#define _M68K_STRING_H_ + +#include <asm/setup.h> +#include <asm/page.h> + +#define __HAVE_ARCH_STRCPY +static inline char * strcpy(char * dest,const char *src) +{ + char *xdest = dest; + + __asm__ __volatile__ + ("1:\tmoveb %1@+,%0@+\n\t" + "jne 1b" + : "=a" (dest), "=a" (src) + : "0" (dest), "1" (src) : "memory"); + return xdest; +} + +#define __HAVE_ARCH_STRNCPY +static inline char * strncpy(char *dest, const char *src, size_t n) +{ + char *xdest = dest; + + if (n == 0) + return xdest; + + __asm__ __volatile__ + ("1:\tmoveb %1@+,%0@+\n\t" + "jeq 2f\n\t" + "subql #1,%2\n\t" + "jne 1b\n\t" + "2:" + : "=a" (dest), "=a" (src), "=d" (n) + : "0" (dest), "1" (src), "2" (n) + : "memory"); + return xdest; +} + +#define __HAVE_ARCH_STRCAT +static inline char * strcat(char * dest, const char * src) +{ + char *tmp = dest; + + while (*dest) + dest++; + while ((*dest++ = *src++)) + ; + + return tmp; +} + +#define __HAVE_ARCH_STRNCAT +static 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 +static inline char * strchr(const char * s, int c) +{ + const char ch = c; + + for(; *s != ch; ++s) + if (*s == '\0') + return( NULL ); + return( (char *) s); +} + +#if 0 +#define __HAVE_ARCH_STRPBRK +static 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 ); +} +#endif + +#if 0 +#define __HAVE_ARCH_STRSPN +static 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; +} +#endif + +/* strstr !! */ + +#define __HAVE_ARCH_STRLEN +static inline size_t strlen(const char * s) +{ + const char *sc; + for (sc = s; *sc != '\0'; ++sc) ; + return(sc - s); +} + +/* strnlen !! */ + +#define __HAVE_ARCH_STRCMP +static inline int strcmp(const char * cs,const char * ct) +{ + char __res; + + __asm__ + ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ + "cmpb %1@+,%2\n\t" /* compare a byte */ + "jne 2f\n\t" /* not equal, break out */ + "tstb %2\n\t" /* at end of cs? */ + "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) + : "0" (cs), "1" (ct)); + return __res; +} + +#define __HAVE_ARCH_STRNCMP +static inline int strncmp(const char * cs,const char * ct,size_t count) +{ + char __res; + + if (!count) + return 0; + __asm__ + ("1:\tmovb %0@+,%3\n\t" /* get *cs */ + "cmpb %1@+,%3\n\t" /* compare a byte */ + "jne 3f\n\t" /* not equal, break out */ + "tstb %3\n\t" /* at end of cs? */ + "jeq 4f\n\t" /* yes, all done */ + "subql #1,%2\n\t" /* no, adjust count */ + "jne 1b\n\t" /* more to do, keep going */ + "2:\tmoveq #0,%3\n\t" /* strings are equal */ + "jra 4f\n\t" + "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */ + "4:" + : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res) + : "0" (cs), "1" (ct), "2" (count)); + return __res; +} + +#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 + */ +static inline void * __memset_g(void * s, int c, size_t count) +{ + void *xs = s; + size_t temp; + + if (!count) + return xs; + + c &= 0xff; + c |= c << 8; + c |= c << 16; + + if (count < 36){ + long *ls = s; + + 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; + } + + 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; +} + +/* + * __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 + */ +static inline void * __memset_page(void * s,int c,size_t count) +{ + unsigned long data, tmp; + void *xs = s; + + c = c & 255; + data = c | (c << 8); + data |= data << 16; + +#ifdef CPU_M68040_OR_M68060_ONLY + + if (((unsigned long) s) & 0x0f) + __memset_g(s, c, count); + else{ + unsigned long *sp = s; + *sp++ = data; + *sp++ = data; + *sp++ = data; + *sp++ = data; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %2@+,%0@+\n\t" + ".chip 68k\n\t" + "subqw #8,%2\n\t" + "subqw #8,%2\n\t" + "dbra %1,1b\n\t" + : "=a" (sp), "=d" (tmp) + : "a" (s), "0" (sp), "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 + + return xs; +} + +extern void *memset(void *,int,__kernel_size_t); + +#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_g((s),(c),(count))) + +#define __HAVE_ARCH_MEMCPY +extern void * memcpy(void *, const void *, size_t ); +/* + * __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 + */ +static inline void * __memcpy_page(void * to, const void * from, size_t count) +{ + unsigned long tmp; + void *xto = to; + +#ifdef CPU_M68040_OR_M68060_ONLY + + if (((unsigned long) to | (unsigned long) from) & 0x0f) + return memcpy(to, from, count); + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %1@+,%0@+\n\t" + "move16 %1@+,%0@+\n\t" + ".chip 68k\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 +static inline void * memmove(void * dest,const void * src, size_t n) +{ + void *xdest = dest; + size_t temp; + + if (!n) + return xdest; + + if (dest < src) + { + 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 + { + 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 __HAVE_ARCH_MEMCMP +extern int memcmp(const void * ,const void * ,size_t ); +#define memcmp(cs, ct, n) \ +(__builtin_constant_p(n) ? \ + __builtin_memcmp((cs),(ct),(n)) : \ + memcmp((cs),(ct),(n))) + +#define __HAVE_ARCH_MEMCHR +static inline void *memchr(const void *cs, int c, size_t count) +{ + /* Someone else can optimize this, I don't care - tonym@mac.linux-m68k.org */ + unsigned char *ret = (unsigned char *)cs; + for(;count>0;count--,ret++) + if(*ret == c) return ret; + + return NULL; +} + +#endif /* _M68K_STRING_H_ */ diff --git a/include/asm-m68k/sun3-head.h b/include/asm-m68k/sun3-head.h new file mode 100644 index 000000000000..f799d95bad53 --- /dev/null +++ b/include/asm-m68k/sun3-head.h @@ -0,0 +1,12 @@ +/* $Id: head.h,v 1.32 1996/12/04 00:12:48 ecd Exp $ */ +#ifndef __SUN3_HEAD_H +#define __SUN3_HEAD_H + +#define KERNBASE 0xE000000 /* First address the kernel will eventually be */ +#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */ +#define BI_START (KERNBASE + 0x3000) /* beginning of the bootinfo records */ +#define FC_CONTROL 3 +#define FC_SUPERD 5 +#define FC_CPU 7 + +#endif /* __SUN3_HEAD_H */ diff --git a/include/asm-m68k/sun3_pgalloc.h b/include/asm-m68k/sun3_pgalloc.h new file mode 100644 index 000000000000..fd8241117649 --- /dev/null +++ b/include/asm-m68k/sun3_pgalloc.h @@ -0,0 +1,95 @@ +/* sun3_pgalloc.h -- + * reorganization around 2.3.39, routines moved from sun3_pgtable.h + * + * + * 02/27/2002 -- Modified to support "highpte" implementation in 2.5.5 (Sam) + * + * moved 1/26/2000 Sam Creasey + */ + +#ifndef _SUN3_PGALLOC_H +#define _SUN3_PGALLOC_H + +#include <asm/tlb.h> + +/* FIXME - when we get this compiling */ +/* erm, now that it's compiling, what do we do with it? */ +#define _KERNPG_TABLE 0 + +extern const char bad_pmd_string[]; + +#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) + + +static inline void pte_free_kernel(pte_t * pte) +{ + free_page((unsigned long) pte); +} + +static inline void pte_free(struct page *page) +{ + __free_page(page); +} + +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) + +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, + unsigned long address) +{ + unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT); + + if (!page) + return NULL; + + memset((void *)page, 0, PAGE_SIZE); + return (pte_t *) (page); +} + +static inline struct page *pte_alloc_one(struct mm_struct *mm, + unsigned long address) +{ + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); + + if (page == NULL) + return NULL; + + clear_highpage(page); + return page; + +} + +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) +{ + pmd_val(*pmd) = __pa((unsigned long)pte); +} + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page) +{ + pmd_val(*pmd) = __pa((unsigned long)page_address(page)); +} + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +#define pmd_free(x) do { } while (0) +#define __pmd_free_tlb(tlb, x) do { } while (0) + +static inline void pgd_free(pgd_t * pgd) +{ + free_page((unsigned long) pgd); +} + +static inline pgd_t * pgd_alloc(struct mm_struct *mm) +{ + pgd_t *new_pgd; + + new_pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL); + memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE); + memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT)); + return new_pgd; +} + +#define pgd_populate(mm, pmd, pte) BUG() + +#endif /* SUN3_PGALLOC_H */ diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h new file mode 100644 index 000000000000..e974bb072047 --- /dev/null +++ b/include/asm-m68k/sun3_pgtable.h @@ -0,0 +1,238 @@ +#ifndef _SUN3_PGTABLE_H +#define _SUN3_PGTABLE_H + +#include <asm/sun3mmu.h> + +#ifndef __ASSEMBLY__ +#include <asm/virtconvert.h> +#include <linux/linkage.h> + +/* + * This file contains all the things which change drastically for the sun3 + * pagetable stuff, to avoid making too much of a mess of the generic m68k + * `pgtable.h'; this should only be included from the generic file. --m + */ + +/* For virtual address to physical address conversion */ +#define VTOP(addr) __pa(addr) +#define PTOV(addr) __va(addr) + + +#endif /* !__ASSEMBLY__ */ + +/* These need to be defined for compatibility although the sun3 doesn't use them */ +#define _PAGE_NOCACHE030 0x040 +#define _CACHEMASK040 (~0x060) +#define _PAGE_NOCACHE_S 0x040 + +/* Page protection values within PTE. */ +#define SUN3_PAGE_VALID (0x80000000) +#define SUN3_PAGE_WRITEABLE (0x40000000) +#define SUN3_PAGE_SYSTEM (0x20000000) +#define SUN3_PAGE_NOCACHE (0x10000000) +#define SUN3_PAGE_ACCESSED (0x02000000) +#define SUN3_PAGE_MODIFIED (0x01000000) + + +/* Externally used page protection values. */ +#define _PAGE_PRESENT (SUN3_PAGE_VALID) +#define _PAGE_ACCESSED (SUN3_PAGE_ACCESSED) + +#define PTE_FILE_MAX_BITS 28 + +/* Compound page protection values. */ +//todo: work out which ones *should* have SUN3_PAGE_NOCACHE and fix... +// is it just PAGE_KERNEL and PAGE_SHARED? +#define PAGE_NONE __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_SHARED __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_COPY __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_READONLY __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_KERNEL __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_SYSTEM \ + | SUN3_PAGE_NOCACHE \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_MODIFIED) +#define PAGE_INIT __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_SYSTEM \ + | SUN3_PAGE_NOCACHE) + +/* + * Page protections for initialising protection_map. The sun3 has only two + * protection settings, valid (implying read and execute) and writeable. These + * are as close as we can get... + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +/* Use these fake page-protections on PMDs. */ +#define SUN3_PMD_VALID (0x00000001) +#define SUN3_PMD_MASK (0x0000003F) +#define SUN3_PMD_MAGIC (0x0000002B) + +#ifndef __ASSEMBLY__ + +/* + * 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) pfn_pte(page_to_pfn(page), (pgprot)) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & SUN3_PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + +#define pmd_set(pmdp,ptep) do {} while (0) + +static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) +{ + pgd_val(*pgdp) = virt_to_phys(pmdp); +} + +#define __pte_page(pte) \ +((unsigned long) __va ((pte_val (pte) & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT)) +#define __pmd_page(pmd) \ +((unsigned long) __va (pmd_val (pmd) & PAGE_MASK)) + +static inline int pte_none (pte_t pte) { return !pte_val (pte); } +static inline int pte_present (pte_t pte) { return pte_val (pte) & SUN3_PAGE_VALID; } +static inline void pte_clear (struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + pte_val (*ptep) = 0; +} + +#define pte_pfn(pte) (pte_val(pte) & SUN3_PAGE_PGNUM_MASK) +#define pfn_pte(pfn, pgprot) \ +({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; }) + +#define pte_page(pte) (mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)) +#define pmd_page(pmd) (mem_map+((__pmd_page(pmd) - PAGE_OFFSET) >> PAGE_SHIFT)) + + +static inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); } +#define pmd_none(pmd) pmd_none2(&(pmd)) +//static inline int pmd_bad (pmd_t pmd) { return (pmd_val (pmd) & SUN3_PMD_MASK) != SUN3_PMD_MAGIC; } +static inline int pmd_bad2 (pmd_t *pmd) { return 0; } +#define pmd_bad(pmd) pmd_bad2(&(pmd)) +static inline int pmd_present2 (pmd_t *pmd) { return pmd_val (*pmd) & SUN3_PMD_VALID; } +/* #define pmd_present(pmd) pmd_present2(&(pmd)) */ +#define pmd_present(pmd) (!pmd_none2(&(pmd))) +static inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; } + +static inline int pgd_none (pgd_t pgd) { return 0; } +static inline int pgd_bad (pgd_t pgd) { return 0; } +static inline int pgd_present (pgd_t pgd) { return 1; } +static inline void pgd_clear (pgd_t *pgdp) {} + + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not... + * [we have the full set here even if they don't change from m68k] + */ +static inline int pte_read(pte_t pte) { return 1; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & SUN3_PAGE_WRITEABLE; } +static inline int pte_exec(pte_t pte) { return 1; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & SUN3_PAGE_MODIFIED; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } + +static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; } +static inline pte_t pte_rdprotect(pte_t pte) { return pte; } +static inline pte_t pte_exprotect(pte_t pte) { return pte; } +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; } +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= SUN3_PAGE_WRITEABLE; return pte; } +static inline pte_t pte_mkread(pte_t pte) { return pte; } +static inline pte_t pte_mkexec(pte_t pte) { return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= SUN3_PAGE_MODIFIED; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= SUN3_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mknocache(pte_t pte) { pte_val(pte) |= SUN3_PAGE_NOCACHE; return pte; } +// use this version when caches work... +//static inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; } +// until then, use: +static inline pte_t pte_mkcache(pte_t pte) { return pte; } + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; + +/* Find an entry in a pagetable directory. */ +#define pgd_index(address) ((address) >> PGDIR_SHIFT) + +#define pgd_offset(mm, address) \ +((mm)->pgd + pgd_index(address)) + +/* Find an entry in a kernel pagetable directory. */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* Find an entry in the second-level pagetable. */ +static inline pmd_t *pmd_offset (pgd_t *pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +static inline unsigned long pte_to_pgoff(pte_t pte) +{ + return pte.pte & SUN3_PAGE_PGNUM_MASK; +} + +static inline pte_t pgoff_to_pte(inline unsigned off) +{ + pte_t pte = { off + SUN3_PAGE_ACCESSED }; + return pte; +} + + +/* Find an entry in the third-level pagetable. */ +#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) +#define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address)) +/* FIXME: should we bother with kmap() here? */ +#define pte_offset_map(pmd, address) ((pte_t *)kmap(pmd_page(*pmd)) + pte_index(address)) +#define pte_offset_map_nested(pmd, address) pte_offset_map(pmd, address) +#define pte_unmap(pte) kunmap(pte) +#define pte_unmap_nested(pte) kunmap(pte) + +/* Macros to (de)construct the fake PTEs representing swap pages. */ +#define __swp_type(x) ((x).val & 0x7F) +#define __swp_offset(x) (((x).val) >> 7) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) | ((offset) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +#endif /* !__ASSEMBLY__ */ +#endif /* !_SUN3_PGTABLE_H */ diff --git a/include/asm-m68k/sun3ints.h b/include/asm-m68k/sun3ints.h new file mode 100644 index 000000000000..fd838eb14213 --- /dev/null +++ b/include/asm-m68k/sun3ints.h @@ -0,0 +1,49 @@ +/* + * sun3ints.h -- Linux/Sun3 interrupt handling code definitions + * + * Erik Verbruggen (erik@bigmama.xtdnet.nl) + * + * 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 SUN3INTS_H +#define SUN3INTS_H + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/kernel_stat.h> +#include <linux/interrupt.h> +#include <linux/seq_file.h> +#include <asm/segment.h> +#include <asm/intersil.h> +#include <asm/oplib.h> + +#define SUN3_INT_VECS 192 + +void sun3_enable_irq(unsigned int irq); +void sun3_disable_irq(unsigned int irq); +int sun3_request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id + ); +extern void sun3_init_IRQ (void); +extern irqreturn_t (*sun3_default_handler[]) (int, void *, struct pt_regs *); +extern irqreturn_t (*sun3_inthandler[]) (int, void *, struct pt_regs *); +extern void sun3_free_irq (unsigned int irq, void *dev_id); +extern void sun3_enable_interrupts (void); +extern void sun3_disable_interrupts (void); +extern int show_sun3_interrupts(struct seq_file *, void *); +extern irqreturn_t sun3_process_int(int, struct pt_regs *); +extern volatile unsigned char* sun3_intreg; + +/* master list of VME vectors -- don't fuck with this */ +#define SUN3_VEC_FLOPPY 0x40 +#define SUN3_VEC_VMESCSI0 0x40 +#define SUN3_VEC_VMESCSI1 0x41 +#define SUN3_VEC_CG 0xA8 + + +#endif /* SUN3INTS_H */ diff --git a/include/asm-m68k/sun3mmu.h b/include/asm-m68k/sun3mmu.h new file mode 100644 index 000000000000..6c8c17d047a1 --- /dev/null +++ b/include/asm-m68k/sun3mmu.h @@ -0,0 +1,170 @@ +/* + * Definitions for Sun3 custom MMU. + */ +#ifndef __SUN3_MMU_H__ +#define __SUN3_MMU_H__ + +#include <asm/movs.h> +#include <asm/sun3-head.h> + +/* MMU characteristics. */ +#define SUN3_SEGMAPS_PER_CONTEXT 2048 +#define SUN3_PMEGS_NUM 256 +#define SUN3_CONTEXTS_NUM 8 + +#define SUN3_PMEG_SIZE_BITS 17 +#define SUN3_PMEG_SIZE (1 << SUN3_PMEG_SIZE_BITS) +#define SUN3_PMEG_MASK (SUN3_PMEG_SIZE - 1) + +#define SUN3_PTE_SIZE_BITS 13 +#define SUN3_PTE_SIZE (1 << SUN3_PTE_SIZE_BITS) +#define SUN3_PTE_MASK (SUN3_PTE_SIZE - 1) + +#define SUN3_CONTROL_MASK (0x0FFFFFFC) +#define SUN3_INVALID_PMEG 255 +#define SUN3_INVALID_CONTEXT 255 + +#define AC_IDPROM 0x00000000 /* 34 ID PROM, R/O, byte, 32 bytes */ +#define AC_PAGEMAP 0x10000000 /* 3 Pagemap R/W, long */ +#define AC_SEGMAP 0x20000000 /* 3 Segment map, byte */ +#define AC_CONTEXT 0x30000000 /* 34c current mmu-context */ +#define AC_SENABLE 0x40000000 /* 34c system dvma/cache/reset enable reg*/ +#define AC_UDVMA_ENB 0x50000000 /* 34 Not used on Sun boards, byte */ +#define AC_BUS_ERROR 0x60000000 /* 34 Cleared on read, byte. */ +#define AC_SYNC_ERR 0x60000000 /* c fault type */ +#define AC_SYNC_VA 0x60000004 /* c fault virtual address */ +#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */ +#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */ +#define AC_LEDS 0x70000000 /* 34 Zero turns on LEDs, byte */ +#define AC_CACHETAGS 0x80000000 /* 34c direct access to the VAC tags */ +#define AC_CACHEDDATA 0x90000000 /* 3 c direct access to the VAC data */ +#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */ +#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */ +#define AC_BOOT_SCC 0xF0000000 /* 34 bypass to access Zilog 8530. byte.*/ + +#define SUN3_PAGE_CHG_MASK (SUN3_PAGE_PGNUM_MASK \ + | SUN3_PAGE_ACCESSED | SUN3_PAGE_MODIFIED) + +/* Bus access type within PTE. */ +#define SUN3_PAGE_TYPE_MASK (0x0c000000) +#define SUN3_PAGE_TYPE_MEMORY (0x00000000) +#define SUN3_PAGE_TYPE_IO (0x04000000) +#define SUN3_PAGE_TYPE_VME16 (0x08000000) +#define SUN3_PAGE_TYPE_VME32 (0x0c000000) + +/* Mask for page number within PTE. */ +#define SUN3_PAGE_PGNUM_MASK (0x0007FFFF) + +/* Bits within bus-error register. */ +#define SUN3_BUSERR_WATCHDOG (0x01) +#define SUN3_BUSERR_unused (0x02) +#define SUN3_BUSERR_FPAENERR (0x04) +#define SUN3_BUSERR_FPABERR (0x08) +#define SUN3_BUSERR_VMEBERR (0x10) +#define SUN3_BUSERR_TIMEOUT (0x20) +#define SUN3_BUSERR_PROTERR (0x40) +#define SUN3_BUSERR_INVALID (0x80) + +#ifndef __ASSEMBLY__ + +/* Read bus error status register (implicitly clearing it). */ +static inline unsigned char sun3_get_buserr(void) +{ + unsigned char sfc, c; + + GET_SFC (sfc); + SET_SFC (FC_CONTROL); + GET_CONTROL_BYTE (AC_BUS_ERROR, c); + SET_SFC (sfc); + + return c; +} + +/* Read segmap from hardware MMU. */ +static inline unsigned long sun3_get_segmap(unsigned long addr) +{ + register unsigned long entry; + unsigned char c, sfc; + + GET_SFC (sfc); + SET_SFC (FC_CONTROL); + GET_CONTROL_BYTE (AC_SEGMAP | (addr & SUN3_CONTROL_MASK), c); + SET_SFC (sfc); + entry = c; + + return entry; +} + +/* Write segmap to hardware MMU. */ +static inline void sun3_put_segmap(unsigned long addr, unsigned long entry) +{ + unsigned char sfc; + + GET_DFC (sfc); + SET_DFC (FC_CONTROL); + SET_CONTROL_BYTE (AC_SEGMAP | (addr & SUN3_CONTROL_MASK), entry); + SET_DFC (sfc); + + return; +} + +/* Read PTE from hardware MMU. */ +static inline unsigned long sun3_get_pte(unsigned long addr) +{ + register unsigned long entry; + unsigned char sfc; + + GET_SFC (sfc); + SET_SFC (FC_CONTROL); + GET_CONTROL_WORD (AC_PAGEMAP | (addr & SUN3_CONTROL_MASK), entry); + SET_SFC (sfc); + + return entry; +} + +/* Write PTE to hardware MMU. */ +static inline void sun3_put_pte(unsigned long addr, unsigned long entry) +{ + unsigned char sfc; + + GET_DFC (sfc); + SET_DFC (FC_CONTROL); + SET_CONTROL_WORD (AC_PAGEMAP | (addr & SUN3_CONTROL_MASK), entry); + SET_DFC (sfc); + + return; +} + +/* get current context */ +static inline unsigned char sun3_get_context(void) +{ + unsigned char sfc, c; + + GET_SFC(sfc); + SET_SFC(FC_CONTROL); + GET_CONTROL_BYTE(AC_CONTEXT, c); + SET_SFC(sfc); + + return c; +} + +/* set alternate context */ +static inline void sun3_put_context(unsigned char c) +{ + unsigned char dfc; + GET_DFC(dfc); + SET_DFC(FC_CONTROL); + SET_CONTROL_BYTE(AC_CONTEXT, c); + SET_DFC(dfc); + + return; +} + +extern void *sun3_ioremap(unsigned long phys, unsigned long size, + unsigned long type); + +extern int sun3_map_test(unsigned long addr, char *val); + +#endif /* !__ASSEMBLY__ */ + +#endif /* !__SUN3_MMU_H__ */ diff --git a/include/asm-m68k/sun3x.h b/include/asm-m68k/sun3x.h new file mode 100644 index 000000000000..f5691a1ed7cc --- /dev/null +++ b/include/asm-m68k/sun3x.h @@ -0,0 +1,27 @@ +#ifndef SUN3X_H +#define SUN3X_H + +/* hardware addresses */ +#define SUN3X_IOMMU 0x60000000 +#define SUN3X_ENAREG 0x61000000 +#define SUN3X_INTREG 0x61001400 +#define SUN3X_DIAGREG 0x61001800 +#define SUN3X_ZS1 0x62000000 +#define SUN3X_ZS2 0x62002000 +#define SUN3X_LANCE 0x65002000 +#define SUN3X_EEPROM 0x64000000 +#define SUN3X_IDPROM 0x640007d8 +#define SUN3X_VIDEO_BASE 0x50000000 +#define SUN3X_VIDEO_P4ID 0x50300000 +#define SUN3X_ESP_BASE 0x66000000 +#define SUN3X_ESP_DMA 0x66001000 +#define SUN3X_FDC 0x6e000000 +#define SUN3X_FDC_FCR 0x6e000400 +#define SUN3X_FDC_FVR 0x6e000800 + +/* some NVRAM addresses */ +#define SUN3X_EEPROM_CONS (SUN3X_EEPROM + 0x1f) +#define SUN3X_EEPROM_PORTA (SUN3X_EEPROM + 0x58) +#define SUN3X_EEPROM_PORTB (SUN3X_EEPROM + 0x60) + +#endif diff --git a/include/asm-m68k/sun3xflop.h b/include/asm-m68k/sun3xflop.h new file mode 100644 index 000000000000..1ed3b787ee05 --- /dev/null +++ b/include/asm-m68k/sun3xflop.h @@ -0,0 +1,265 @@ +/* sun3xflop.h: Sun3/80 specific parts of the floppy driver. + * + * Derived partially from asm-sparc/floppy.h, which is: + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * + * Sun3x version 2/4/2000 Sam Creasey (sammy@sammy.net) + */ + +#ifndef __ASM_SUN3X_FLOPPY_H +#define __ASM_SUN3X_FLOPPY_H + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/sun3x.h> + +/* default interrupt vector */ +#define SUN3X_FDC_IRQ 0x40 + +/* some constants */ +#define FCR_TC 0x1 +#define FCR_EJECT 0x2 +#define FCR_MTRON 0x4 +#define FCR_DSEL1 0x8 +#define FCR_DSEL0 0x10 + +/* We don't need no stinkin' I/O port allocation crap. */ +#undef release_region +#undef check_region +#undef request_region +#define release_region(X, Y) do { } while(0) +#define check_region(X, Y) (0) +#define request_region(X, Y, Z) (1) + +struct sun3xflop_private { + volatile unsigned char *status_r; + volatile unsigned char *data_r; + volatile unsigned char *fcr_r; + volatile unsigned char *fvr_r; + unsigned char fcr; +} sun3x_fdc; + +/* Super paranoid... */ +#undef HAVE_DISABLE_HLT + +/* Routines unique to each controller type on a Sun. */ +static unsigned char sun3x_82072_fd_inb(int port) +{ + static int once = 0; +// udelay(5); + switch(port & 7) { + default: + printk("floppy: Asked to read unknown port %d\n", port); + panic("floppy: Port bolixed."); + case 4: /* FD_STATUS */ + return (*sun3x_fdc.status_r) & ~STATUS_DMA; + case 5: /* FD_DATA */ + return (*sun3x_fdc.data_r); + case 7: /* FD_DIR */ + /* ugly hack, I can't find a way to actually detect the disk */ + if(!once) { + once = 1; + return 0x80; + } + return 0; + }; + panic("sun_82072_fd_inb: How did I get here?"); +} + +static void sun3x_82072_fd_outb(unsigned char value, int port) +{ +// udelay(5); + switch(port & 7) { + default: + printk("floppy: Asked to write to unknown port %d\n", port); + panic("floppy: Port bolixed."); + case 2: /* FD_DOR */ + /* Oh geese, 82072 on the Sun has no DOR register, + * so we make do with taunting the FCR. + * + * ASSUMPTIONS: There will only ever be one floppy + * drive attached to a Sun controller + * and it will be at drive zero. + */ + + { + unsigned char fcr = sun3x_fdc.fcr; + + if(value & 0x10) { + fcr |= (FCR_DSEL0 | FCR_MTRON); + } else + fcr &= ~(FCR_DSEL0 | FCR_MTRON); + + + if(fcr != sun3x_fdc.fcr) { + *(sun3x_fdc.fcr_r) = fcr; + sun3x_fdc.fcr = fcr; + } + } + break; + case 5: /* FD_DATA */ + *(sun3x_fdc.data_r) = value; + break; + case 7: /* FD_DCR */ + *(sun3x_fdc.status_r) = value; + break; + case 4: /* FD_STATUS */ + *(sun3x_fdc.status_r) = value; + break; + }; + return; +} + + +asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id, + struct pt_regs * regs) +{ + register unsigned char st; + +#undef TRACE_FLPY_INT +#define NO_FLOPPY_ASSEMBLER + +#ifdef TRACE_FLPY_INT + static int calls=0; + static int bytes=0; + static int dma_wait=0; +#endif + if(!doing_pdma) { + floppy_interrupt(irq, dev_id, regs); + return IRQ_HANDLED; + } + +// printk("doing pdma\n");// st %x\n", sun_fdc->status_82072); + +#ifdef TRACE_FLPY_INT + if(!calls) + bytes = virtual_dma_count; +#endif + + { + register int lcount; + register char *lptr; + + for(lcount=virtual_dma_count, lptr=virtual_dma_addr; + lcount; lcount--, lptr++) { +/* st=fd_inb(virtual_dma_port+4) & 0x80 ; */ + st = *(sun3x_fdc.status_r); +/* if(st != 0xa0) */ +/* break; */ + + if((st & 0x80) == 0) { + virtual_dma_count = lcount; + virtual_dma_addr = lptr; + return IRQ_HANDLED; + } + + if((st & 0x20) == 0) + break; + + if(virtual_dma_mode) +/* fd_outb(*lptr, virtual_dma_port+5); */ + *(sun3x_fdc.data_r) = *lptr; + else +/* *lptr = fd_inb(virtual_dma_port+5); */ + *lptr = *(sun3x_fdc.data_r); + } + + virtual_dma_count = lcount; + virtual_dma_addr = lptr; +/* st = fd_inb(virtual_dma_port+4); */ + st = *(sun3x_fdc.status_r); + } + +#ifdef TRACE_FLPY_INT + calls++; +#endif +// printk("st=%02x\n", st); + if(st == 0x20) + return IRQ_HANDLED; + if(!(st & 0x20)) { + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; + doing_pdma = 0; + +#ifdef TRACE_FLPY_INT + printk("count=%x, residue=%x calls=%d bytes=%x dma_wait=%d\n", + virtual_dma_count, virtual_dma_residue, calls, bytes, + dma_wait); + calls = 0; + dma_wait=0; +#endif + + floppy_interrupt(irq, dev_id, regs); + return IRQ_HANDLED; + } + + +#ifdef TRACE_FLPY_INT + if(!virtual_dma_count) + dma_wait++; +#endif + return IRQ_HANDLED; +} + +static int sun3xflop_request_irq(void) +{ + static int once = 0; + int error; + + if(!once) { + once = 1; + error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, SA_INTERRUPT, "floppy", 0); + return ((error == 0) ? 0 : -1); + } else return 0; +} + +static void __init floppy_set_flags(int *ints,int param, int param2); + +static int sun3xflop_init(void) +{ + if(FLOPPY_IRQ < 0x40) + FLOPPY_IRQ = SUN3X_FDC_IRQ; + + sun3x_fdc.status_r = (volatile unsigned char *)SUN3X_FDC; + sun3x_fdc.data_r = (volatile unsigned char *)(SUN3X_FDC+1); + sun3x_fdc.fcr_r = (volatile unsigned char *)SUN3X_FDC_FCR; + sun3x_fdc.fvr_r = (volatile unsigned char *)SUN3X_FDC_FVR; + sun3x_fdc.fcr = 0; + + /* Last minute sanity check... */ + if(*sun3x_fdc.status_r == 0xff) { + return -1; + } + + *sun3x_fdc.fvr_r = FLOPPY_IRQ; + + *sun3x_fdc.fcr_r = FCR_TC; + udelay(10); + *sun3x_fdc.fcr_r = 0; + + /* Success... */ + floppy_set_flags(0, 1, FD_BROKEN_DCL); // I don't know how to detect this. + allowed_drive_mask = 0x01; + return (int) SUN3X_FDC; +} + +/* I'm not precisely sure this eject routine works */ +static int sun3x_eject(void) +{ + if(MACH_IS_SUN3X) { + + sun3x_fdc.fcr |= (FCR_DSEL0 | FCR_EJECT); + *(sun3x_fdc.fcr_r) = sun3x_fdc.fcr; + udelay(10); + sun3x_fdc.fcr &= ~(FCR_DSEL0 | FCR_EJECT); + *(sun3x_fdc.fcr_r) = sun3x_fdc.fcr; + } + + return 0; +} + +#define fd_eject(drive) sun3x_eject() + +#endif /* !(__ASM_SUN3X_FLOPPY_H) */ diff --git a/include/asm-m68k/sun3xprom.h b/include/asm-m68k/sun3xprom.h new file mode 100644 index 000000000000..6735efcf5f6d --- /dev/null +++ b/include/asm-m68k/sun3xprom.h @@ -0,0 +1,43 @@ +/* Useful PROM locations */ + +#ifndef SUN3X_PROM_H +#define SUN3X_PROM_H + +extern void (*sun3x_putchar)(int); +extern int (*sun3x_getchar)(void); +extern int (*sun3x_mayget)(void); +extern int (*sun3x_mayput)(int); + +void sun3x_reboot(void); +void sun3x_abort(void); +void sun3x_prom_init(void); +unsigned long sun3x_prom_ptov(unsigned long pa, unsigned long size); + +/* interesting hardware locations */ +#define SUN3X_IOMMU 0x60000000 +#define SUN3X_ENAREG 0x61000000 +#define SUN3X_INTREG 0x61001400 +#define SUN3X_DIAGREG 0x61001800 +#define SUN3X_ZS1 0x62000000 +#define SUN3X_ZS2 0x62002000 +#define SUN3X_LANCE 0x65002000 +#define SUN3X_EEPROM 0x64000000 +#define SUN3X_IDPROM 0x640007d8 +#define SUN3X_VIDEO_BASE 0x50400000 +#define SUN3X_VIDEO_REGS 0x50300000 + +/* vector table */ +#define SUN3X_PROM_BASE 0xfefe0000 +#define SUN3X_P_GETCHAR (SUN3X_PROM_BASE + 20) +#define SUN3X_P_PUTCHAR (SUN3X_PROM_BASE + 24) +#define SUN3X_P_MAYGET (SUN3X_PROM_BASE + 28) +#define SUN3X_P_MAYPUT (SUN3X_PROM_BASE + 32) +#define SUN3X_P_REBOOT (SUN3X_PROM_BASE + 96) +#define SUN3X_P_SETLEDS (SUN3X_PROM_BASE + 144) +#define SUN3X_P_ABORT (SUN3X_PROM_BASE + 152) + +/* mapped area */ +#define SUN3X_MAP_START 0xfee00000 +#define SUN3X_MAP_END 0xff000000 + +#endif diff --git a/include/asm-m68k/suspend.h b/include/asm-m68k/suspend.h new file mode 100644 index 000000000000..57b3ddb4d269 --- /dev/null +++ b/include/asm-m68k/suspend.h @@ -0,0 +1,6 @@ +#ifndef _M68K_SUSPEND_H +#define _M68K_SUSPEND_H + +/* Dummy include. */ + +#endif /* _M68K_SUSPEND_H */ diff --git a/include/asm-m68k/swim_iop.h b/include/asm-m68k/swim_iop.h new file mode 100644 index 000000000000..f29b67876b01 --- /dev/null +++ b/include/asm-m68k/swim_iop.h @@ -0,0 +1,221 @@ +/* + * SWIM access through the IOP + * Written by Joshua M. Thompson + */ + +/* IOP number and channel number for the SWIM */ + +#define SWIM_IOP IOP_NUM_ISM +#define SWIM_CHAN 1 + +/* Command code: */ + +#define CMD_INIT 0x01 /* Initialize */ +#define CMD_SHUTDOWN 0x02 /* Shutdown */ +#define CMD_START_POLL 0x03 /* Start insert/eject polling */ +#define CMD_STOP_POLL 0x04 /* Stop insert/eject polling */ +#define CMD_SETHFSTAG 0x05 /* Set HFS tag buffer address */ +#define CMD_STATUS 0x06 /* Status */ +#define CMD_EJECT 0x07 /* Eject */ +#define CMD_FORMAT 0x08 /* Format */ +#define CMD_FORMAT_VERIFY 0x09 /* Format and Verify */ +#define CMD_WRITE 0x0A /* Write */ +#define CMD_READ 0x0B /* Read */ +#define CMD_READ_VERIFY 0x0C /* Read and Verify */ +#define CMD_CACHE_CTRL 0x0D /* Cache control */ +#define CMD_TAGBUFF_CTRL 0x0E /* Tag buffer control */ +#define CMD_GET_ICON 0x0F /* Get Icon */ + +/* Drive types: */ + +/* note: apple sez DRV_FDHD is 4, but I get back a type */ +/* of 5 when I do a drive status check on my FDHD */ + +#define DRV_NONE 0 /* No drive */ +#define DRV_UNKNOWN 1 /* Unspecified drive */ +#define DRV_400K 2 /* 400K */ +#define DRV_800K 3 /* 400K/800K */ +#define DRV_FDHD 5 /* 400K/800K/720K/1440K */ +#define DRV_HD20 7 /* Apple HD20 */ + +/* Format types: */ + +#define FMT_HD20 0x0001 /* Apple HD20 */ +#define FMT_400K 0x0002 /* 400K (GCR) */ +#define FMT_800K 0x0004 /* 800K (GCR) */ +#define FMT_720K 0x0008 /* 720K (MFM) */ +#define FMT_1440K 0x0010 /* 1.44M (MFM) */ + +#define FMD_KIND_400K 1 +#define FMD_KIND_800K 2 +#define FMD_KIND_720K 3 +#define FMD_KIND_1440K 1 + +/* Icon Flags: */ + +#define ICON_MEDIA 0x01 /* Have IOP supply media icon */ +#define ICON_DRIVE 0x01 /* Have IOP supply drive icon */ + +/* Error codes: */ + +#define gcrOnMFMErr -400 /* GCR (400/800K) on HD media */ +#define verErr -84 /* verify failed */ +#define fmt2Err -83 /* can't get enough sync during format */ +#define fmt1Err -82 /* can't find sector 0 after track format */ +#define sectNFErr -81 /* can't find sector */ +#define seekErr -80 /* drive error during seek */ +#define spdAdjErr -79 /* can't set drive speed */ +#define twoSideErr -78 /* drive is single-sided */ +#define initIWMErr -77 /* error during initialization */ +#define tk0badErr -76 /* track zero is bad */ +#define cantStepErr -75 /* drive error during step */ +#define wrUnderrun -74 /* write underrun occurred */ +#define badDBtSlp -73 /* bad data bitslip marks */ +#define badDCksum -72 /* bad data checksum */ +#define noDtaMkErr -71 /* can't find data mark */ +#define badBtSlpErr -70 /* bad address bitslip marks */ +#define badCksmErr -69 /* bad address-mark checksum */ +#define dataVerErr -68 /* read-verify failed */ +#define noAdrMkErr -67 /* can't find an address mark */ +#define noNybErr -66 /* no nybbles? disk is probably degaussed */ +#define offLinErr -65 /* no disk in drive */ +#define noDriveErr -64 /* drive isn't connected */ +#define nsDrvErr -56 /* no such drive */ +#define paramErr -50 /* bad positioning information */ +#define wPrErr -44 /* write protected */ +#define openErr -23 /* already initialized */ + +#ifndef __ASSEMBLY__ + +struct swim_drvstatus { + __u16 curr_track; /* Current track number */ + __u8 write_prot; /* 0x80 if disk is write protected */ + __u8 disk_in_drive; /* 0x01 or 0x02 if a disk is in the drive */ + __u8 installed; /* 0x01 if drive installed, 0xFF if not */ + __u8 num_sides; /* 0x80 if two-sided format supported */ + __u8 two_sided; /* 0xff if two-sided format diskette */ + __u8 new_interface; /* 0x00 if old 400K drive, 0xFF if newer */ + __u16 errors; /* Disk error count */ + struct { /* 32 bits */ + __u16 reserved; + __u16 :4; + __u16 external:1; /* Drive is external */ + __u16 scsi:1; /* Drive is a SCSI drive */ + __u16 fixed:1; /* Drive has fixed media */ + __u16 secondary:1; /* Drive is secondary drive */ + __u8 type; /* Drive type */ + } info; + __u8 mfm_drive; /* 0xFF if this is an FDHD drive */ + __u8 mfm_disk; /* 0xFF if 720K/1440K (MFM) disk */ + __u8 mfm_format; /* 0x00 if 720K, 0xFF if 1440K */ + __u8 ctlr_type; /* 0x00 if IWM, 0xFF if SWIM */ + __u16 curr_format; /* Current format type */ + __u16 allowed_fmt; /* Allowed format types */ + __u32 num_blocks; /* Number of blocks on disk */ + __u8 icon_flags; /* Icon flags */ + __u8 unusued; +}; + +/* Commands issued from the host to the IOP: */ + +struct swimcmd_init { + __u8 code; /* CMD_INIT */ + __u8 unusued; + __u16 error; + __u8 drives[28]; /* drive type list */ +}; + +struct swimcmd_startpoll { + __u8 code; /* CMD_START_POLL */ + __u8 unusued; + __u16 error; +}; + +struct swimcmd_sethfstag { + __u8 code; /* CMD_SETHFSTAG */ + __u8 unusued; + __u16 error; + caddr_t tagbuf; /* HFS tag buffer address */ +}; + +struct swimcmd_status { + __u8 code; /* CMD_STATUS */ + __u8 drive_num; + __u16 error; + struct swim_drvstatus status; +}; + +struct swimcmd_eject { + __u8 code; /* CMD_EJECT */ + __u8 drive_num; + __u16 error; + struct swim_drvstatus status; +}; + +struct swimcmd_format { + __u8 code; /* CMD_FORMAT */ + __u8 drive_num; + __u16 error; + union { + struct { + __u16 fmt; /* format kind */ + __u8 hdrbyte; /* fmt byte for hdr (0=default) */ + __u8 interleave; /* interleave (0 = default) */ + caddr_t databuf; /* sector data buff (0=default */ + caddr_t tagbuf; /* tag data buffer (0=default) */ + } f; + struct swim_drvstatus status; + } p; +}; + +struct swimcmd_fmtverify { + __u8 code; /* CMD_FORMAT_VERIFY */ + __u8 drive_num; + __u16 error; +}; + +struct swimcmd_rw { + __u8 code; /* CMD_READ, CMD_WRITE or CMD_READ_VERIFY */ + __u8 drive_num; + __u16 error; + caddr_t buffer; /* R/W buffer address */ + __u32 first_block; /* Starting block */ + __u32 num_blocks; /* Number of blocks */ + __u8 tag[12]; /* tag data */ +}; + +struct swimcmd_cachectl { + __u8 code; /* CMD_CACHE_CTRL */ + __u8 unused; + __u16 error; + __u8 enable; /* Nonzero to enable cache */ + __u8 install; /* +1 = install, -1 = remove, 0 = neither */ +}; + +struct swimcmd_tagbufctl { + __u8 code; /* CMD_TAGBUFF_CTRL */ + __u8 unused; + __u16 error; + caddr_t buf; /* buffer address or 0 to disable */ +}; + +struct swimcmd_geticon { + __u8 code; /* CMD_GET_ICON */ + __u8 drive_num; + __u16 error; + caddr_t buffer; /* Nuffer address */ + __u16 kind; /* 0 = media icon, 1 = drive icon */ + __u16 unused; + __u16 max_bytes; /* maximum byte count */ +}; + +/* Messages from the SWIM IOP to the host CPU: */ + +struct swimmsg_status { + __u8 code; /* 1 = insert, 2 = eject, 3 = status changed */ + __u8 drive_num; + __u16 error; + struct swim_drvstatus status; +}; + +#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h new file mode 100644 index 000000000000..64d3481df74c --- /dev/null +++ b/include/asm-m68k/system.h @@ -0,0 +1,201 @@ +#ifndef _M68K_SYSTEM_H +#define _M68K_SYSTEM_H + +#include <linux/config.h> /* get configuration macros */ +#include <linux/linkage.h> +#include <linux/kernel.h> +#include <asm/segment.h> +#include <asm/entry.h> + +#ifdef __KERNEL__ + +/* + * 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. + */ +/* + * 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 + */ +asmlinkage void resume(void); +#define switch_to(prev,next,last) do { \ + register void *_prev __asm__ ("a0") = (prev); \ + register void *_next __asm__ ("a1") = (next); \ + register void *_last __asm__ ("d1"); \ + __asm__ __volatile__("jbsr resume" \ + : "=a" (_prev), "=a" (_next), "=d" (_last) \ + : "0" (_prev), "1" (_next) \ + : "d0", "d2", "d3", "d4", "d5"); \ + (last) = _last; \ +} while (0) + + +/* interrupt control.. */ +#if 0 +#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory") +#else +#include <linux/hardirq.h> +#define local_irq_enable() ({ \ + if (MACH_IS_Q40 || !hardirq_count()) \ + asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \ +}) +#endif +#define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory") +#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory") +#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory") + +static inline int irqs_disabled(void) +{ + unsigned long flags; + local_save_flags(flags); + return flags & ~ALLOWINT; +} + +/* For spinlocks etc */ +#define local_irq_save(x) ({ local_save_flags(x); local_irq_disable(); }) + +/* + * Force strict CPU ordering. + * Not really required on m68k... + */ +#define nop() do { asm volatile ("nop"); barrier(); } while (0) +#define mb() barrier() +#define rmb() barrier() +#define wmb() barrier() +#define read_barrier_depends() do { } while(0) +#define set_mb(var, value) do { xchg(&var, value); } while (0) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while(0) + + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) + +#ifndef CONFIG_RMW_INSNS +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + unsigned long flags, tmp; + + local_irq_save(flags); + + switch (size) { + case 1: + tmp = *(u8 *)ptr; + *(u8 *)ptr = x; + x = tmp; + break; + case 2: + tmp = *(u16 *)ptr; + *(u16 *)ptr = x; + x = tmp; + break; + case 4: + tmp = *(u32 *)ptr; + *(u32 *)ptr = x; + x = tmp; + break; + default: + BUG(); + } + + local_irq_restore(flags); + return x; +} +#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 + +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ +#ifdef CONFIG_RMW_INSNS +#define __HAVE_ARCH_CMPXCHG 1 + +static inline unsigned long __cmpxchg(volatile void *p, unsigned long old, + unsigned long new, int size) +{ + switch (size) { + case 1: + __asm__ __volatile__ ("casb %0,%2,%1" + : "=d" (old), "=m" (*(char *)p) + : "d" (new), "0" (old), "m" (*(char *)p)); + break; + case 2: + __asm__ __volatile__ ("casw %0,%2,%1" + : "=d" (old), "=m" (*(short *)p) + : "d" (new), "0" (old), "m" (*(short *)p)); + break; + case 4: + __asm__ __volatile__ ("casl %0,%2,%1" + : "=d" (old), "=m" (*(int *)p) + : "d" (new), "0" (old), "m" (*(int *)p)); + break; + } + return old; +} + +#define cmpxchg(ptr,o,n)\ + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ + (unsigned long)(n),sizeof(*(ptr)))) +#endif + +#define arch_align_stack(x) (x) + +#endif /* __KERNEL__ */ + +#endif /* _M68K_SYSTEM_H */ diff --git a/include/asm-m68k/termbits.h b/include/asm-m68k/termbits.h new file mode 100644 index 000000000000..e9eec3eb0718 --- /dev/null +++ b/include/asm-m68k/termbits.h @@ -0,0 +1,175 @@ +#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 +#define IUTF8 0040000 + +/* 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 B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#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 000000000000..857f0c9a9120 --- /dev/null +++ b/include/asm-m68k/termios.h @@ -0,0 +1,108 @@ +#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 +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* 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 +#define N_X25 6 /* X.25 async */ +#define N_6PACK 7 +#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */ +#define N_R3964 9 /* Reserved for Simatic R3964 module */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */ +#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 +#define N_HCI 15 /* Bluetooth HCI UART */ + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + unsigned short tmp; \ + get_user(tmp, &(termio)->c_iflag); \ + (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ + get_user(tmp, &(termio)->c_oflag); \ + (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ + get_user(tmp, &(termio)->c_cflag); \ + (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ + get_user(tmp, &(termio)->c_lflag); \ + (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ + get_user((termios)->c_line, &(termio)->c_line); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* _M68K_TERMIOS_H */ diff --git a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h new file mode 100644 index 000000000000..5f58939c59db --- /dev/null +++ b/include/asm-m68k/thread_info.h @@ -0,0 +1,118 @@ +#ifndef _ASM_M68K_THREAD_INFO_H +#define _ASM_M68K_THREAD_INFO_H + +#include <asm/types.h> +#include <asm/processor.h> +#include <asm/page.h> + +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ + __u32 cpu; /* should always be 0 on m68k */ + struct restart_block restart_block; + + __u8 supervisor_stack[0]; +}; + +#define PREEMPT_ACTIVE 0x4000000 + +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +/* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */ +#if PAGE_SHIFT == 13 /* 8k machines */ +#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,0)) +#define free_thread_info(ti) free_pages((unsigned long)(ti),0) +#else /* otherwise assume 4k pages */ +#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,1)) +#define free_thread_info(ti) free_pages((unsigned long)(ti),1) +#endif /* PAGE_SHIFT == 13 */ + +//#define init_thread_info (init_task.thread.info) +#define init_stack (init_thread_union.stack) + +#define current_thread_info() (current->thread_info) + + +#define __HAVE_THREAD_FUNCTIONS + +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_DELAYED_TRACE 1 /* single step a syscall */ +#define TIF_NOTIFY_RESUME 2 /* resumption notification requested */ +#define TIF_SIGPENDING 3 /* signal pending */ +#define TIF_NEED_RESCHED 4 /* rescheduling necessary */ +#define TIF_MEMDIE 5 + +extern int thread_flag_fixme(void); + +/* + * flag set/clear/test wrappers + * - pass TIF_xxxx constants to these functions + */ + +#define __set_tsk_thread_flag(tsk, flag, val) ({ \ + switch (flag) { \ + case TIF_SIGPENDING: \ + tsk->thread.work.sigpending = val; \ + break; \ + case TIF_NEED_RESCHED: \ + tsk->thread.work.need_resched = val; \ + break; \ + case TIF_SYSCALL_TRACE: \ + tsk->thread.work.syscall_trace = val; \ + break; \ + case TIF_MEMDIE: \ + tsk->thread.work.memdie = val; \ + break; \ + default: \ + thread_flag_fixme(); \ + } \ +}) + +#define __get_tsk_thread_flag(tsk, flag) ({ \ + int ___res; \ + switch (flag) { \ + case TIF_SIGPENDING: \ + ___res = tsk->thread.work.sigpending; \ + break; \ + case TIF_NEED_RESCHED: \ + ___res = tsk->thread.work.need_resched; \ + break; \ + case TIF_SYSCALL_TRACE: \ + ___res = tsk->thread.work.syscall_trace;\ + break; \ + case TIF_MEMDIE: \ + ___res = tsk->thread.work.memdie;\ + break; \ + default: \ + ___res = thread_flag_fixme(); \ + } \ + ___res; \ +}) + +#define __get_set_tsk_thread_flag(tsk, flag, val) ({ \ + int __res = __get_tsk_thread_flag(tsk, flag); \ + __set_tsk_thread_flag(tsk, flag, val); \ + __res; \ +}) + +#define set_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, ~0) +#define clear_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, 0) +#define test_and_set_tsk_thread_flag(tsk, flag) __get_set_tsk_thread_flag(tsk, flag, ~0) +#define test_tsk_thread_flag(tsk, flag) __get_tsk_thread_flag(tsk, flag) + +#define set_thread_flag(flag) set_tsk_thread_flag(current, flag) +#define clear_thread_flag(flag) clear_tsk_thread_flag(current, flag) +#define test_thread_flag(flag) test_tsk_thread_flag(current, flag) + +#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED) +#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED) + +#endif /* _ASM_M68K_THREAD_INFO_H */ diff --git a/include/asm-m68k/timex.h b/include/asm-m68k/timex.h new file mode 100644 index 000000000000..b87f2f278f67 --- /dev/null +++ b/include/asm-m68k/timex.h @@ -0,0 +1,18 @@ +/* + * linux/include/asm-m68k/timex.h + * + * m68k architecture timex specifications + */ +#ifndef _ASMm68k_TIMEX_H +#define _ASMm68k_TIMEX_H + +#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ + +typedef unsigned long cycles_t; + +static inline cycles_t get_cycles(void) +{ + return 0; +} + +#endif diff --git a/include/asm-m68k/tlb.h b/include/asm-m68k/tlb.h new file mode 100644 index 000000000000..1785cff73449 --- /dev/null +++ b/include/asm-m68k/tlb.h @@ -0,0 +1,20 @@ +#ifndef _M68K_TLB_H +#define _M68K_TLB_H + +/* + * m68k doesn't need any special per-pte or + * per-vma handling.. + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +/* + * .. because we flush the whole mm when it + * fills up. + */ +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + +#include <asm-generic/tlb.h> + +#endif /* _M68K_TLB_H */ diff --git a/include/asm-m68k/tlbflush.h b/include/asm-m68k/tlbflush.h new file mode 100644 index 000000000000..8e61ccffe13a --- /dev/null +++ b/include/asm-m68k/tlbflush.h @@ -0,0 +1,230 @@ +#ifndef _M68K_TLBFLUSH_H +#define _M68K_TLBFLUSH_H + +#include <linux/config.h> + +#ifndef CONFIG_SUN3 + +#include <asm/current.h> + +static inline void flush_tlb_kernel_page(void *addr) +{ + if (CPU_IS_040_OR_060) { + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); + set_fs(old_fs); + } else + __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); +} + +/* + * flush all user-space atc entries. + */ +static inline void __flush_tlb(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".chip 68040\n\t" + "pflushan\n\t" + ".chip 68k"); + else + __asm__ __volatile__("pflush #0,#4"); +} + +static inline void __flush_tlb040_one(unsigned long addr) +{ + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + if (CPU_IS_040_OR_060) + __flush_tlb040_one(addr); + else + __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".chip 68040\n\t" + "pflusha\n\t" + ".chip 68k"); + else + __asm__ __volatile__("pflusha"); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->active_mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) +{ + if (vma->vm_mm == current->active_mm) { + mm_segment_t old_fs = get_fs(); + set_fs(USER_DS); + __flush_tlb_one(addr); + set_fs(old_fs); + } +} + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + if (vma->vm_mm == current->active_mm) + __flush_tlb(); +} + +static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + flush_tlb_all(); +} + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + +#else + + +/* Reserved PMEGs. */ +extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; +extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM]; +extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM]; +extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM]; + +/* Flush all userspace mappings one by one... (why no flush command, + sun?) */ +static inline void flush_tlb_all(void) +{ + unsigned long addr; + unsigned char ctx, oldctx; + + oldctx = sun3_get_context(); + for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) { + for(ctx = 0; ctx < 8; ctx++) { + sun3_put_context(ctx); + sun3_put_segmap(addr, SUN3_INVALID_PMEG); + } + } + + sun3_put_context(oldctx); + /* erase all of the userspace pmeg maps, we've clobbered them + all anyway */ + for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) { + if(pmeg_alloc[addr] == 1) { + pmeg_alloc[addr] = 0; + pmeg_ctx[addr] = 0; + pmeg_vaddr[addr] = 0; + } + } + +} + +/* Clear user TLB entries within the context named in mm */ +static inline void flush_tlb_mm (struct mm_struct *mm) +{ + unsigned char oldctx; + unsigned char seg; + unsigned long i; + + oldctx = sun3_get_context(); + sun3_put_context(mm->context); + + for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) { + seg = sun3_get_segmap(i); + if(seg == SUN3_INVALID_PMEG) + continue; + + sun3_put_segmap(i, SUN3_INVALID_PMEG); + pmeg_alloc[seg] = 0; + pmeg_ctx[seg] = 0; + pmeg_vaddr[seg] = 0; + } + + sun3_put_context(oldctx); + +} + +/* Flush a single TLB page. In this case, we're limited to flushing a + single PMEG */ +static inline void flush_tlb_page (struct vm_area_struct *vma, + unsigned long addr) +{ + unsigned char oldctx; + unsigned char i; + + oldctx = sun3_get_context(); + sun3_put_context(vma->vm_mm->context); + addr &= ~SUN3_PMEG_MASK; + if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG) + { + pmeg_alloc[i] = 0; + pmeg_ctx[i] = 0; + pmeg_vaddr[i] = 0; + sun3_put_segmap (addr, SUN3_INVALID_PMEG); + } + sun3_put_context(oldctx); + +} +/* Flush a range of pages from TLB. */ + +static inline void flush_tlb_range (struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned char seg, oldctx; + + start &= ~SUN3_PMEG_MASK; + + oldctx = sun3_get_context(); + sun3_put_context(mm->context); + + while(start < end) + { + if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) + goto next; + if(pmeg_ctx[seg] == mm->context) { + pmeg_alloc[seg] = 0; + pmeg_ctx[seg] = 0; + pmeg_vaddr[seg] = 0; + } + sun3_put_segmap(start, SUN3_INVALID_PMEG); + next: + start += SUN3_PMEG_SIZE; + } +} + +static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + flush_tlb_all(); +} + +/* Flush kernel page from TLB. */ +static inline void flush_tlb_kernel_page (unsigned long addr) +{ + sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG); +} + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + +#endif + +#endif /* _M68K_TLBFLUSH_H */ diff --git a/include/asm-m68k/topology.h b/include/asm-m68k/topology.h new file mode 100644 index 000000000000..ca173e9f26ff --- /dev/null +++ b/include/asm-m68k/topology.h @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_TOPOLOGY_H +#define _ASM_M68K_TOPOLOGY_H + +#include <asm-generic/topology.h> + +#endif /* _ASM_M68K_TOPOLOGY_H */ diff --git a/include/asm-m68k/traps.h b/include/asm-m68k/traps.h new file mode 100644 index 000000000000..475056191252 --- /dev/null +++ b/include/asm-m68k/traps.h @@ -0,0 +1,265 @@ +/* + * 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 + +#ifndef __ASSEMBLY__ + +typedef void (*e_vector)(void); + +extern e_vector vectors[]; + +#endif + +#define VEC_RESETSP (0) +#define VEC_RESETPC (1) +#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_RESV12 (12) +#define VEC_COPROC (13) +#define VEC_FORMAT (14) +#define VEC_UNINT (15) +#define VEC_RESV16 (16) +#define VEC_RESV17 (17) +#define VEC_RESV18 (18) +#define VEC_RESV19 (19) +#define VEC_RESV20 (20) +#define VEC_RESV21 (21) +#define VEC_RESV22 (22) +#define VEC_RESV23 (23) +#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_MMUCFG (56) +#define VEC_MMUILL (57) +#define VEC_MMUACC (58) +#define VEC_RESV59 (59) +#define VEC_UNIMPEA (60) +#define VEC_UNIMPII (61) +#define VEC_RESV62 (62) +#define VEC_RESV63 (63) +#define VEC_USER (64) + +#define VECOFF(vec) ((vec)<<2) + +#ifndef __ASSEMBLY__ + +/* 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_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_TWE | 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 /* __ASSEMBLY__ */ + +#endif /* _M68K_TRAPS_H */ diff --git a/include/asm-m68k/types.h b/include/asm-m68k/types.h new file mode 100644 index 000000000000..f391cbe39b96 --- /dev/null +++ b/include/asm-m68k/types.h @@ -0,0 +1,69 @@ +#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. + */ + +#ifndef __ASSEMBLY__ + +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 + +#endif /* __ASSEMBLY__ */ + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#define BITS_PER_LONG 32 + +#ifndef __ASSEMBLY__ + +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; + +/* DMA addresses are always 32-bits wide */ + +typedef u32 dma_addr_t; +typedef u32 dma64_addr_t; + +typedef unsigned short kmem_bufctl_t; + +#endif /* __ASSEMBLY__ */ + +#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 000000000000..605e6cb811f8 --- /dev/null +++ b/include/asm-m68k/uaccess.h @@ -0,0 +1,893 @@ +#ifndef __M68K_UACCESS_H +#define __M68K_UACCESS_H + +/* + * User space memory access functions + */ +#include <linux/errno.h> +#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 + +/* this function will go away soon - use access_ok() instead */ +static inline int __deprecated 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; +}; + + +/* + * 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; \ + case 8: \ + __pu_err = __constant_copy_to_user(ptr, &__pu_val, 8); \ + 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" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 21b,2b\n" \ + " .long 1b,2b\n" \ + ".previous" \ + : "=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; \ + case 8: \ + __gu_err = __constant_copy_from_user(&__gu_val, ptr, 8); \ + 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" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : "=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: movel %2,%%d0\n" + "71:clrl (%0)+\n" + " subql #1,%%d0\n" + " jne 71b\n" + " lsll #2,%2\n" + " addl %4,%2\n" + " btst #1,%4\n" + " jne 81f\n" + " btst #0,%4\n" + " jne 91f\n" + " jra 6b\n" + "8: addql #2,%2\n" + "81:clrw (%0)+\n" + " btst #0,%4\n" + " jne 91f\n" + " jra 6b\n" + "9: addql #1,%2\n" + "91:clrb (%0)+\n" + " jra 6b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,7b\n" + " .long 3b,8b\n" + " .long 5b,9b\n" + ".previous" + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) + : "d"(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" + "60:addql #1,%2\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" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,60b\n" + " .long 22b,6b\n" + " .long 2b,6b\n" + " .long 24b,7b\n" + " .long 3b,60b\n" + " .long 4b,7b\n" + " .long 25b,8b\n" + " .long 5b,8b\n" + ".previous" + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp) + : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4) + : "memory"); + 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: movel %2,%%d0\n" \ + "13: clrl (%0)+\n" \ + " subql #1,%%d0\n" \ + " jne 13b\n" \ + " lsll #2,%2\n" \ + fixup "\n" \ + " jra 12f\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 10b,11b\n" \ + ".previous\n" \ + copy "\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" + " clrb (%0)+\n" + " jra 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".previous" + : "=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" + " clrw (%0)+\n" + " jra 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".previous" + : "=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" + " clrw (%0)+\n" + "5: addql #1,%2\n" + " clrb (%0)+\n" + " jra 3b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 2b,5b\n" + ".previous" + : "=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" + " clrl (%0)+\n" + " jra 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".previous" + : "=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" + " clrl (%0)+\n" + "5: addql #4,%2\n" + " clrl (%0)+\n" + " jra 3b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 2b,5b\n" + ".previous" + : "=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" + " clrl (%0)+\n" + "6: addql #4,%2\n" + " clrl (%0)+\n" + "7: addql #4,%2\n" + " clrl (%0)+\n" + " jra 4b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,5b\n" + " .long 2b,6b\n" + " .long 3b,7b\n" + ".previous" + : "=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" + " clrl (%0)+\n" + "7: addql #4,%2\n" + " clrl (%0)+\n" + "8: addql #4,%2\n" + " clrl (%0)+\n" + "9: addql #4,%2\n" + " clrl (%0)+\n" + " jra 5b\n" + ".previous\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" + ".previous" + : "=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\n" + " clrb (%0)+", + /* copy */ + "2: movesb (%1)+,%%d0\n" + " moveb %%d0,(%0)+\n" + ".section __ex_table,\"a\"\n" + " .long 2b,1b\n" + ".previous"); + break; + case 2: + __copy_from_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2\n" + " clrw (%0)+", + /* copy */ + "2: movesw (%1)+,%%d0\n" + " movew %%d0,(%0)+\n" + ".section __ex_table,\"a\"\n" + " .long 2b,1b\n" + ".previous"); + break; + case 3: + __copy_from_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2\n" + " clrw (%0)+\n" + "2: addql #1,%2\n" + " clrb (%0)+", + /* 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\n" + ".previous"); + 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" \ + "41:\n" \ + ".section .fixup,\"ax\"\n" \ + " .even\n" \ + "22: addql #1,%2\n" \ + "12: lsll #2,%2\n" \ + fixup "\n" \ + " jra 13f\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 10b,22b\n" \ + " .long 31b,12b\n" \ + " .long 11b,12b\n" \ + " .long 41b,22b\n" \ + ".previous\n" \ + copy "\n" \ + "13:" \ + : "=a"(to), "=a"(from), "=d"(n) \ + : "0"(to), "1"(from), "2"(n/4) \ + : "d0", "memory") + +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +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" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n " + " .long 21b,2b\n" + " .long 1b,2b\n" + ".previous" + : "=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" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,2b\n" + " .long 1b,2b\n" + ".previous" + : "=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" + ".previous\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" + ".previous" + : "=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" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 21b,2b\n" + " .long 1b,2b\n" + ".previous" + : "=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" + ".previous\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" + ".previous" + : "=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" + ".previous\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" + ".previous" + : "=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" + ".previous\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" + ".previous" + : "=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\n" + ".previous"); + 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\n" + ".previous"); + break; + case 3: + __copy_to_user_big(to, from, n, + /* fixup */ + "1: addql #2,%2\n" + "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\n" + ".previous"); + 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)) + +#define __copy_from_user(to, from, n) copy_from_user(to, from, n) +#define __copy_to_user(to, from, n) 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" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,4b\n" + " .long 12b,4b\n" + ".previous" + : "=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 on exception, a value greater than N if too long + */ +static inline long strnlen_user(const char *src, long n) +{ + long res; + + res = -(long)src; + __asm__ __volatile__ + ("1:\n" + " tstl %2\n" + " jeq 3f\n" + "2: movesb (%1)+,%%d0\n" + "22:\n" + " subql #1,%2\n" + " tstb %%d0\n" + " jne 1b\n" + " jra 4f\n" + "3:\n" + " addql #1,%0\n" + "4:\n" + " addl %1,%0\n" + "5:\n" + ".section .fixup,\"ax\"\n" + " .even\n" + "6: moveq %3,%0\n" + " jra 5b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 2b,6b\n" + " .long 22b,6b\n" + ".previous" + : "=d"(res), "=a"(src), "=d"(n) + : "i"(0), "0"(res), "1"(src), "2"(n) + : "d0"); + return res; +} + +#define strlen_user(str) strnlen_user(str, 32767) + +/* + * Zero Userspace + */ + +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" + "61:addql #1,%1\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" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,61b\n" + " .long 2b,6b\n" + " .long 3b,61b\n" + " .long 24b,7b\n" + " .long 4b,7b\n" + " .long 25b,8b\n" + " .long 5b,8b\n" + ".previous" + : "=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/ucontext.h b/include/asm-m68k/ucontext.h new file mode 100644 index 000000000000..e4e22669edc0 --- /dev/null +++ b/include/asm-m68k/ucontext.h @@ -0,0 +1,30 @@ +#ifndef _M68K_UCONTEXT_H +#define _M68K_UCONTEXT_H + +typedef int greg_t; +#define NGREG 18 +typedef greg_t gregset_t[NGREG]; + +typedef struct fpregset { + int f_fpcntl[3]; + int f_fpregs[8*3]; +} fpregset_t; + +struct mcontext { + int version; + gregset_t gregs; + fpregset_t fpregs; +}; + +#define MCONTEXT_VERSION 2 + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct mcontext uc_mcontext; + unsigned long uc_filler[80]; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif diff --git a/include/asm-m68k/unaligned.h b/include/asm-m68k/unaligned.h new file mode 100644 index 000000000000..804cb3f888fe --- /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 new file mode 100644 index 000000000000..cbabde4f8a45 --- /dev/null +++ b/include/asm-m68k/unistd.h @@ -0,0 +1,465 @@ +#ifndef _ASM_M68K_UNISTD_H_ +#define _ASM_M68K_UNISTD_H_ + +/* + * This file contains the system call numbers. + */ + +#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_umount2 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 */ Obsolete +#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 +#define __NR_getpagesize 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_lchown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_chown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_lchown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_getdents64 220 +#define __NR_gettid 221 +#define __NR_tkill 222 +#define __NR_setxattr 223 +#define __NR_lsetxattr 224 +#define __NR_fsetxattr 225 +#define __NR_getxattr 226 +#define __NR_lgetxattr 227 +#define __NR_fgetxattr 228 +#define __NR_listxattr 229 +#define __NR_llistxattr 230 +#define __NR_flistxattr 231 +#define __NR_removexattr 232 +#define __NR_lremovexattr 233 +#define __NR_fremovexattr 234 +#define __NR_futex 235 +#define __NR_sendfile64 236 +#define __NR_mincore 237 +#define __NR_madvise 238 +#define __NR_fcntl64 239 +#define __NR_readahead 240 +#define __NR_io_setup 241 +#define __NR_io_destroy 242 +#define __NR_io_getevents 243 +#define __NR_io_submit 244 +#define __NR_io_cancel 245 +#define __NR_fadvise64 246 +#define __NR_exit_group 247 +#define __NR_lookup_dcookie 248 +#define __NR_epoll_create 249 +#define __NR_epoll_ctl 250 +#define __NR_epoll_wait 251 +#define __NR_remap_file_pages 252 +#define __NR_set_tid_address 253 +#define __NR_timer_create 254 +#define __NR_timer_settime 255 +#define __NR_timer_gettime 256 +#define __NR_timer_getoverrun 257 +#define __NR_timer_delete 258 +#define __NR_clock_settime 259 +#define __NR_clock_gettime 260 +#define __NR_clock_getres 261 +#define __NR_clock_nanosleep 262 +#define __NR_statfs64 263 +#define __NR_fstatfs64 264 +#define __NR_tgkill 265 +#define __NR_utimes 266 +#define __NR_fadvise64_64 267 +#define __NR_mbind 268 +#define __NR_get_mempolicy 269 +#define __NR_set_mempolicy 270 +#define __NR_mq_open 271 +#define __NR_mq_unlink 272 +#define __NR_mq_timedsend 273 +#define __NR_mq_timedreceive 274 +#define __NR_mq_notify 275 +#define __NR_mq_getsetattr 276 +#define __NR_waitid 277 +#define __NR_vserver 278 +#define __NR_add_key 279 +#define __NR_request_key 280 +#define __NR_keyctl 281 + +#define NR_syscalls 282 + +/* user-visible error numbers are in the range -1 - -124: see + <asm-m68k/errno.h> */ + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + /* avoid using res which is declared to be in register d0; \ + errno might expand to a function call and clobber it. */ \ + int __err = -(res); \ + errno = __err; \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type,name) \ +type name(void) \ +{ \ +register long __res __asm__ ("%d0") = __NR_##name; \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) ); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,atype,a) \ +type name(atype a) \ +{ \ +register long __res __asm__ ("%d0") = __NR_##name; \ +register long __a __asm__ ("%d1") = (long)(a); \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) \ + : "d" (__a) ); \ +__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; \ +register long __a __asm__ ("%d1") = (long)(a); \ +register long __b __asm__ ("%d2") = (long)(b); \ +__asm__ __volatile__ ("trap #0" \ + : "+d" (__res) \ + : "d" (__a), "d" (__b) \ + ); \ +__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; \ +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) \ + : "d" (__a), "d" (__b), \ + "d" (__c) \ + ); \ +__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; \ +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) \ + : "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d) \ + ); \ +__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; \ +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) \ + : "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d), "d" (__e) \ + ); \ +__syscall_return(type,__res); \ +} + +#ifdef __KERNEL__ +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION +#endif + +#ifdef __KERNEL_SYSCALLS__ + +#include <linux/compiler.h> +#include <linux/interrupt.h> +#include <linux/types.h> + +/* + * 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(pid_t,setsid) +static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) +static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,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) + +asmlinkage long sys_mmap2( + unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); +asmlinkage int sys_execve(char *name, char **argv, char **envp); +asmlinkage int sys_pipe(unsigned long *fildes); +asmlinkage int sys_ptrace(long request, long pid, long addr, long data); +struct pt_regs; +struct sigaction; +asmlinkage long sys_rt_sigaction(int sig, + const struct sigaction __user *act, + struct sigaction __user *oact, + size_t sigsetsize); + +#endif + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") + +#endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/include/asm-m68k/user.h b/include/asm-m68k/user.h new file mode 100644 index 000000000000..e8d5a64c7e79 --- /dev/null +++ b/include/asm-m68k/user.h @@ -0,0 +1,89 @@ +#ifndef _M68K_USER_H +#define _M68K_USER_H + +#include <asm/page.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 user_regs_struct *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/virtconvert.h b/include/asm-m68k/virtconvert.h new file mode 100644 index 000000000000..8c4e8037b898 --- /dev/null +++ b/include/asm-m68k/virtconvert.h @@ -0,0 +1,76 @@ +#ifndef __VIRT_CONVERT__ +#define __VIRT_CONVERT__ + +/* + * Macros used for converting between virtual and physical mappings. + */ + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <linux/compiler.h> +#include <asm/setup.h> +#include <asm/page.h> + +#ifdef CONFIG_AMIGA +#include <asm/amigahw.h> +#endif + +/* + * Change virtual addresses to physical addresses and vv. + */ +#ifndef CONFIG_SUN3 +extern unsigned long mm_vtop(unsigned long addr) __attribute_const__; +extern unsigned long mm_ptov(unsigned long addr) __attribute_const__; +#else +static inline unsigned long mm_vtop(unsigned long vaddr) +{ + return __pa(vaddr); +} + +static inline unsigned long mm_ptov(unsigned long paddr) +{ + return (unsigned long)__va(paddr); +} +#endif + +#ifdef CONFIG_SINGLE_MEMORY_CHUNK +static inline unsigned long virt_to_phys(void *vaddr) +{ + return (unsigned long)vaddr - PAGE_OFFSET + m68k_memory[0].addr; +} + +static inline void * phys_to_virt(unsigned long paddr) +{ + return (void *)(paddr - m68k_memory[0].addr + PAGE_OFFSET); +} +#else +static inline unsigned long virt_to_phys(void *address) +{ + return mm_vtop((unsigned long)address); +} + +static inline void *phys_to_virt(unsigned long address) +{ + return (void *) mm_ptov(address); +} +#endif + +/* Permanent address of a page. */ +#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT)) +#define page_to_phys(page) virt_to_phys((void *)__page_address(page)) + +/* + * IO bus memory addresses are 1:1 with the physical address, + * except on the PCI bus of the Hades. + */ +#ifdef CONFIG_HADES +#define virt_to_bus(a) (virt_to_phys(a) + (MACH_IS_HADES ? 0x80000000 : 0)) +#define bus_to_virt(a) (phys_to_virt((a) - (MACH_IS_HADES ? 0x80000000 : 0))) +#else +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt +#endif + +#endif +#endif diff --git a/include/asm-m68k/vuid_event.h b/include/asm-m68k/vuid_event.h new file mode 100644 index 000000000000..52ecb521a395 --- /dev/null +++ b/include/asm-m68k/vuid_event.h @@ -0,0 +1,4 @@ +#ifndef _M68K_VUID_EVENT_H +#define _M68K_VUID_EVENT_H +#include <asm-sparc/vuid_event.h> +#endif diff --git a/include/asm-m68k/xor.h b/include/asm-m68k/xor.h new file mode 100644 index 000000000000..c82eb12a5b18 --- /dev/null +++ b/include/asm-m68k/xor.h @@ -0,0 +1 @@ +#include <asm-generic/xor.h> diff --git a/include/asm-m68k/zorro.h b/include/asm-m68k/zorro.h new file mode 100644 index 000000000000..cf816588bedb --- /dev/null +++ b/include/asm-m68k/zorro.h @@ -0,0 +1,45 @@ +#ifndef _ASM_M68K_ZORRO_H +#define _ASM_M68K_ZORRO_H + +#include <asm/raw_io.h> + +#define z_readb raw_inb +#define z_readw raw_inw +#define z_readl raw_inl + +#define z_writeb raw_outb +#define z_writew raw_outw +#define z_writel raw_outl + +#define z_memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define z_memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define z_memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +static inline void *z_remap_nocache_ser(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +static inline void *z_remap_nocache_nonser(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER); +} + +static inline void *z_remap_writethrough(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} +static inline void *z_remap_fullcache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +#define z_unmap iounmap +#define z_iounmap iounmap +#define z_ioremap z_remap_nocache_ser + +#endif /* _ASM_M68K_ZORRO_H */ |