diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
commit | db7d4daea91e105e3859cf461d7e53b9b77454b2 (patch) | |
tree | 9bb65b95440af09e8aca63abe56970dd3360cc57 /include/asm-ppc | |
parent | 9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff) |
Merge with Linux 2.2.8.
Diffstat (limited to 'include/asm-ppc')
36 files changed, 868 insertions, 700 deletions
diff --git a/include/asm-ppc/adb.h b/include/asm-ppc/adb.h index 58fcb8abe..c13b67bb5 100644 --- a/include/asm-ppc/adb.h +++ b/include/asm-ppc/adb.h @@ -21,6 +21,16 @@ #define ADB_RET_OK 0 #define ADB_RET_TIMEOUT 3 +/* The kind of ADB request. The controller may emulate some + of all of those CUDA/PMU packet kinds */ +#define ADB_PACKET 0 +#define CUDA_PACKET 1 +#define ERROR_PACKET 2 +#define TIMER_PACKET 3 +#define POWER_PACKET 4 +#define MACIIC_PACKET 5 +#define PMU_PACKET 6 + #ifdef __KERNEL__ struct adb_request { @@ -41,25 +51,50 @@ struct adb_ids { unsigned char id[16]; }; -extern enum adb_hw { - ADB_NONE, ADB_VIACUDA, ADB_VIAPMU, ADB_MACIO -} adb_hardware; +/* Messages sent thru the client_list notifier. You should NOT stop + the operation, at least not with this version */ +enum adb_message { + ADB_MSG_POWERDOWN, /* Currently called before sleep only */ + ADB_MSG_PRE_RESET, /* Called before resetting the bus */ + ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */ +}; +extern struct notifier_block *adb_client_list; + +/* Kind of ADB controller */ +enum adb_hw { + ADB_NONE, ADB_VIACUDA, ADB_VIAPMU, ADB_MACIO, ADB_UNKNOWN +}; -extern int (*adb_send_request)(struct adb_request *req, int sync); -extern int (*adb_autopoll)(int devs); -extern int (*adb_reset_bus)(void); +/* Definition of a controller */ +extern struct adb_controller { + enum adb_hw kind; + + int (*send_request)(struct adb_request *req, int sync); + int (*autopoll)(int devs); + int (*reset_bus)(void); + void (*poll)(void); +} *adb_controller; +extern enum adb_hw adb_hardware; /* Values for adb_request flags */ #define ADBREQ_REPLY 1 /* expect reply */ #define ADBREQ_SYNC 2 /* poll until done */ void adb_init(void); + int adb_request(struct adb_request *req, void (*done)(struct adb_request *), int flags, int nbytes, ...); int adb_register(int default_id,int handler_id,struct adb_ids *ids, void (*handler)(unsigned char *, int, struct pt_regs *, int)); void adb_input(unsigned char *, int, struct pt_regs *, int); +int adb_try_handler_change(int address, int new_id); +int adb_get_infos(int address, int *original_address, int *handler_id); + +int adb_reset_bus(void); + +void adb_poll(void); + #endif /* __KERNEL__ */ #endif /* __PPC_ADB_H */ diff --git a/include/asm-ppc/bootx.h b/include/asm-ppc/bootx.h index 85bea1469..ad69eaa54 100644 --- a/include/asm-ppc/bootx.h +++ b/include/asm-ppc/bootx.h @@ -18,7 +18,14 @@ #pragma options align=power #endif -#define BOOT_INFO_VERSION 1 +/* On boostrap entry: + * + * r3 = 0x426f6f58 ('BooX') + * r4 = pointer to boot_infos + * r5 = NULL + */ + +#define BOOT_INFO_VERSION 2 #define BOOT_INFO_COMPATIBLE_VERSION 1 /* Here are the boot informations that are passed to the bootstrap @@ -31,8 +38,12 @@ typedef struct boot_infos /* backward compatible down to version: */ unsigned long compatible_version; + /* NEW (vers. 2) this holds the current _logical_ base addr of + the frame buffer (for use by early boot message) */ + unsigned char* logicalDisplayBase; + /* Set to 0 by current BootX */ - unsigned long unused[3]; + unsigned long unused[2]; /* The device tree (internal addresses relative to the beginning of the tree, * device tree offset relative to the beginning of this structure). */ @@ -55,17 +66,18 @@ typedef struct boot_infos /* Kernel command line arguments (offset from this structure) */ unsigned long kernelParamsOffset; - + } boot_infos_t; /* (*) The format of the colormap is 256 * 3 * 2 bytes. Each color index is represented * by 3 short words containing a 16 bits (unsigned) color component. * Later versions may contain the gamma table for direct-color devices here. */ -#define BOOTX_COLORTABLE_SIZE (256UL*3UL*2UL); +#define BOOTX_COLORTABLE_SIZE (256UL*3UL*2UL) #ifdef macintosh #pragma options align=reset #endif #endif + diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h index 431dc7a49..0d54430d2 100644 --- a/include/asm-ppc/cache.h +++ b/include/asm-ppc/cache.h @@ -13,7 +13,11 @@ #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) #define L1_CACHE_PAGES 8 +#define SMP_CACHE_BYTES L1_CACHE_BYTES + #if defined(__KERNEL__) && !defined(__ASSEMBLY__) +extern void flush_dcache_range(unsigned long start, unsigned long stop); + static inline unsigned long unlock_dcache(void) { #ifndef CONFIG_8xx diff --git a/include/asm-ppc/cuda.h b/include/asm-ppc/cuda.h index 2bfa7c127..39506f64a 100644 --- a/include/asm-ppc/cuda.h +++ b/include/asm-ppc/cuda.h @@ -5,15 +5,6 @@ * 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 -#define PMU_PACKET 6 - /* CUDA commands (2nd byte) */ #define CUDA_WARM_START 0 #define CUDA_AUTOPOLL 1 @@ -41,7 +32,7 @@ void find_via_cuda(void); void via_cuda_init(void); int cuda_request(struct adb_request *req, void (*done)(struct adb_request *), int nbytes, ...); -int cuda_send_request(struct adb_request *req); void cuda_poll(void); +int cuda_present(void); #endif /* __KERNEL */ diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h index b817e055a..3e980e353 100644 --- a/include/asm-ppc/dma.h +++ b/include/asm-ppc/dma.h @@ -35,36 +35,9 @@ /* Doesn't really apply... */ #define MAX_DMA_ADDRESS 0xFFFFFFFF -#if defined(CONFIG_MACH_SPECIFIC) - -#if defined(CONFIG_PREP) -#define DMA_MODE_READ 0x44 -#define DMA_MODE_WRITE 0x48 -#define ISA_DMA_THRESHOLD 0x00ffffff -#endif /* CONFIG_PREP */ - -#if defined(CONFIG_CHRP) -#define DMA_MODE_READ 0x44 -#define DMA_MODE_WRITE 0x48 -#define ISA_DMA_THRESHOLD ~0L -#endif /* CONFIG_CHRP */ - -#ifdef CONFIG_PMAC -#define DMA_MODE_READ 1 -#define DMA_MODE_WRITE 2 -#define ISA_DMA_THRESHOLD ~0L -#endif /* CONFIG_PMAC */ - -#ifdef CONFIG_APUS -/* This is bogus and should go away. */ -#define ISA_DMA_THRESHOLD (0x00ffffff) -#endif - -#else /* in arch/ppc/kernel/setup.c -- Cort */ extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ; extern unsigned long ISA_DMA_THRESHOLD; -#endif #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER @@ -204,7 +177,7 @@ extern long ppc_cs4232_dma, ppc_cs4232_dma2; #define DMA2_EXT_REG 0x4D6 #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ -#define DMA_AUTOINIT 0x10 +#define DMA_AUTOINIT 0x10 extern spinlock_t dma_spin_lock; @@ -223,15 +196,47 @@ static __inline__ void release_dma_lock(unsigned long flags) /* enable/disable a specific DMA channel */ static __inline__ void enable_dma(unsigned int dmanr) { + /* + * The Radstone PPC2 and PPC2a boards have inverted DREQ + * lines (active low) so each command needs to be logically + * ORed with 0x40 + */ + unsigned char ucDmaCmd=0x00; + + if(_prep_type==_PREP_Radstone) + { + switch(ucSystemType) + { + case RS_SYS_TYPE_PPC2: + case RS_SYS_TYPE_PPC2a: + case RS_SYS_TYPE_PPC2ep: + { + /* + * DREQ lines are active low + */ + ucDmaCmd=0x40; + break; + } + + default: + { + /* + * DREQ lines are active high + */ + break; + } + } + } + if (dmanr != 4) { dma_outb(0, DMA2_MASK_REG); /* This may not be enabled */ - dma_outb(0, DMA2_CMD_REG); /* Enable group */ + dma_outb(ucDmaCmd, DMA2_CMD_REG); /* Enable group */ } if (dmanr<=3) { dma_outb(dmanr, DMA1_MASK_REG); - dma_outb(0, DMA1_CMD_REG); /* Enable group */ + dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */ } else { dma_outb(dmanr & 3, DMA2_MASK_REG); @@ -395,9 +400,8 @@ extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a extern void free_dma(unsigned int dmanr); /* release it again */ #ifdef CONFIG_PCI_QUIRKS -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy (0) +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) #endif - #endif /* _ASM_DMA_H */ diff --git a/include/asm-ppc/feature.h b/include/asm-ppc/feature.h index 4264690f8..28a31d945 100644 --- a/include/asm-ppc/feature.h +++ b/include/asm-ppc/feature.h @@ -35,7 +35,6 @@ enum system_feature { FEATURE_Mediabay_floppy_enable, FEATURE_BMac_reset, FEATURE_BMac_IO_enable, - FEATURE_Modem_PowerOn, FEATURE_Modem_Reset, FEATURE_last, }; diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h index cc0db7259..cb195c5f7 100644 --- a/include/asm-ppc/hardirq.h +++ b/include/asm-ppc/hardirq.h @@ -1,22 +1,22 @@ #ifndef __ASM_HARDIRQ_H #define __ASM_HARDIRQ_H -extern unsigned int local_irq_count[NR_CPUS]; +extern unsigned int ppc_local_irq_count[NR_CPUS]; /* * Are we in an interrupt context? Either doing bottom half * or hardware interrupt processing? */ #define in_interrupt() ({ int __cpu = smp_processor_id(); \ - (local_irq_count[__cpu] + local_bh_count[__cpu] != 0); }) + (ppc_local_irq_count[__cpu] + ppc_local_bh_count[__cpu] != 0); }) #ifndef __SMP__ -#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0) +#define hardirq_trylock(cpu) (ppc_local_irq_count[cpu] == 0) #define hardirq_endlock(cpu) do { } while (0) -#define hardirq_enter(cpu) (local_irq_count[cpu]++) -#define hardirq_exit(cpu) (local_irq_count[cpu]--) +#define hardirq_enter(cpu) (ppc_local_irq_count[cpu]++) +#define hardirq_exit(cpu) (ppc_local_irq_count[cpu]--) #define synchronize_irq() do { } while (0) @@ -39,14 +39,14 @@ static inline void release_irqlock(int cpu) static inline void hardirq_enter(int cpu) { - ++local_irq_count[cpu]; + ++ppc_local_irq_count[cpu]; atomic_inc(&global_irq_count); } static inline void hardirq_exit(int cpu) { atomic_dec(&global_irq_count); - --local_irq_count[cpu]; + --ppc_local_irq_count[cpu]; } static inline int hardirq_trylock(int cpu) diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h index cad526b12..c53267b77 100644 --- a/include/asm-ppc/ide.h +++ b/include/asm-ppc/ide.h @@ -11,61 +11,20 @@ #ifndef __ASMPPC_IDE_H #define __ASMPPC_IDE_H -#include <linux/config.h> -#ifdef CONFIG_APUS -#include <linux/hdreg.h> - -#define ide_init_hwif_ports m68k_ide_init_hwif_ports -#include <asm-m68k/ide.h> -#undef ide_init_hwif_ports -#undef insw - -void ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq); -void ide_insw(ide_ioreg_t port, void *buf, int ns); -void ide_outsw(ide_ioreg_t port, void *buf, int ns); -#define insw(port, buf, ns) do { \ - if ( _machine != _MACH_Pmac && _machine != _MACH_apus ) \ - /* this must be the same as insw in io.h!! */ \ - _insw((unsigned short *)((port)+_IO_BASE), (buf), (ns)); \ - else \ - ide_insw((port), (buf), (ns)); \ -} while (0) -#undef outsw -#define outsw(port, buf, ns) do { \ - if ( _machine != _MACH_Pmac && _machine != _MACH_apus ) \ - /* this must be the same as outsw in io.h!! */ \ - _outsw((unsigned short *)((port)+_IO_BASE), (buf), (ns)); \ - else \ - ide_outsw((port), (buf), (ns)); \ -} while (0) -#else /* CONFIG_APUS */ - -#ifdef __KERNEL__ - -#include <linux/hdreg.h> -#include <linux/ioport.h> -#include <asm/io.h> /* so we can redefine insw/outsw */ +#include <linux/sched.h> +#include <asm/processor.h> #ifndef MAX_HWIFS #define MAX_HWIFS 4 #endif -#undef SUPPORT_SLOW_DATA_PORTS -#define SUPPORT_SLOW_DATA_PORTS 0 -#undef SUPPORT_VLB_SYNC -#define SUPPORT_VLB_SYNC 0 - +typedef unsigned int ide_ioreg_t; -#define ide__sti() __sti() +#ifdef __KERNEL__ -typedef unsigned int ide_ioreg_t; -void ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq); -void prep_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq); -void mbx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq); -void pmac_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq); -void chrp_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq); -void ide_insw(ide_ioreg_t port, void *buf, int ns); -void ide_outsw(ide_ioreg_t port, void *buf, int ns); +#include <linux/hdreg.h> +#include <linux/ioport.h> +#include <asm/io.h> extern int pmac_ide_ports_known; extern ide_ioreg_t pmac_ide_regbase[MAX_HWIFS]; @@ -78,222 +37,86 @@ extern ide_ioreg_t chrp_idedma_regbase; /* one for both channels */ extern unsigned int chrp_ide_irq; extern void chrp_ide_probe(void); +struct ide_machdep_calls { + void (*insw)(ide_ioreg_t port, void *buf, int ns); + void (*outsw)(ide_ioreg_t port, void *buf, int ns); + int (*default_irq)(ide_ioreg_t base); + ide_ioreg_t (*default_io_base)(int index); + int (*check_region)(ide_ioreg_t from, unsigned int extent); + void (*request_region)(ide_ioreg_t from, + unsigned int extent, + const char *name); + void (*release_region)(ide_ioreg_t from, + unsigned int extent); + void (*fix_driveid)(struct hd_driveid *id); + void (*ide_init_hwif)(ide_ioreg_t *p, + ide_ioreg_t base, + int *irq); + + int io_base; +}; + +extern struct ide_machdep_calls ppc_ide_md; + +void ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq); +void ide_insw(ide_ioreg_t port, void *buf, int ns); +void ide_outsw(ide_ioreg_t port, void *buf, int ns); +void ppc_generic_ide_fix_driveid(struct hd_driveid *id); + +#undef insw +#define insw(port, buf, ns) do { \ + ppc_ide_md.insw((port), (buf), (ns)); \ +} while (0) + +#undef outsw +#define outsw(port, buf, ns) do { \ + ppc_ide_md.outsw((port), (buf), (ns)); \ +} while (0) + +#undef SUPPORT_SLOW_DATA_PORTS +#define SUPPORT_SLOW_DATA_PORTS 0 +#undef SUPPORT_VLB_SYNC +#define SUPPORT_VLB_SYNC 0 + +#define ide__sti() __sti() + static __inline__ int ide_default_irq(ide_ioreg_t base) { - if ( _machine == _MACH_Pmac ) - return 0; - else if ( _machine == _MACH_mbx ) - /* hardcode IRQ 14 on the MBX */ - return 14+16; - else if ( _machine == _MACH_chrp) { - if (chrp_ide_ports_known == 0) - chrp_ide_probe(); - return chrp_ide_irq; - } - switch (base) { - case 0x1f0: return 13; - case 0x170: return 13; - case 0x1e8: return 11; - case 0x168: return 10; - default: - return 0; - } + return ppc_ide_md.default_irq(base); } static __inline__ ide_ioreg_t ide_default_io_base(int index) { -#if defined(CONFIG_BLK_DEV_IDE_PMAC) - if (_machine == _MACH_Pmac) { - return pmac_ide_regbase[index]; - } -#endif - if (_machine == _MACH_mbx) return index; - if ( _machine == _MACH_chrp ) { - if (chrp_ide_ports_known == 0) - chrp_ide_probe(); - return chrp_ide_regbase[index]; - } - switch (index) { - case 0: return 0x1f0; - case 1: return 0x170; - case 2: return 0x1e8; - case 3: return 0x168; - default: - return 0; - } + return ppc_ide_md.default_io_base(index); } static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) { - if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx)) - return 0; - return check_region(from, extent); + return ppc_ide_md.check_region(from, extent); } static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name) { - if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx) ) - return; - request_region(from, extent, name); + ppc_ide_md.request_region(from, extent, name); } static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent) { - if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx) ) - return; - release_region(from, extent); + ppc_ide_md.release_region(from, extent); } -/* Convert the shorts/longs in hd_driveid from little to big endian; - chars are endian independent, of course, but strings need to be flipped. - (Despite what it says in drivers/block/ide.h, they come up as little endian...) - Changes to linux/hdreg.h may require changes here. */ static __inline__ void ide_fix_driveid (struct hd_driveid *id) { - if (( _machine == _MACH_Pmac ) || (_machine == _MACH_chrp)|| (_machine == _MACH_mbx) ) { - int i; - unsigned short *stringcast; - id->config = __le16_to_cpu(id->config); - id->cyls = __le16_to_cpu(id->cyls); - id->reserved2 = __le16_to_cpu(id->reserved2); - id->heads = __le16_to_cpu(id->heads); - id->track_bytes = __le16_to_cpu(id->track_bytes); - id->sector_bytes = __le16_to_cpu(id->sector_bytes); - id->sectors = __le16_to_cpu(id->sectors); - id->vendor0 = __le16_to_cpu(id->vendor0); - id->vendor1 = __le16_to_cpu(id->vendor1); - id->vendor2 = __le16_to_cpu(id->vendor2); - stringcast = (unsigned short *)&id->serial_no[0]; - for (i=0; i<(20/2); i++) - stringcast[i] = __le16_to_cpu(stringcast[i]); - id->buf_type = __le16_to_cpu(id->buf_type); - id->buf_size = __le16_to_cpu(id->buf_size); - id->ecc_bytes = __le16_to_cpu(id->ecc_bytes); - stringcast = (unsigned short *)&id->fw_rev[0]; - for (i=0; i<(8/2); i++) - stringcast[i] = __le16_to_cpu(stringcast[i]); - stringcast = (unsigned short *)&id->model[0]; - for (i=0; i<(40/2); i++) - stringcast[i] = __le16_to_cpu(stringcast[i]); - id->dword_io = __le16_to_cpu(id->dword_io); - id->reserved50 = __le16_to_cpu(id->reserved50); - id->field_valid = __le16_to_cpu(id->field_valid); - id->cur_cyls = __le16_to_cpu(id->cur_cyls); - id->cur_heads = __le16_to_cpu(id->cur_heads); - id->cur_sectors = __le16_to_cpu(id->cur_sectors); - id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0); - id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1); - id->lba_capacity = __le32_to_cpu(id->lba_capacity); - id->dma_1word = __le16_to_cpu(id->dma_1word); - id->dma_mword = __le16_to_cpu(id->dma_mword); - id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes); - id->eide_dma_min = __le16_to_cpu(id->eide_dma_min); - id->eide_dma_time = __le16_to_cpu(id->eide_dma_time); - id->eide_pio = __le16_to_cpu(id->eide_pio); - id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy); - id->word69 = __le16_to_cpu(id->word69); - id->word70 = __le16_to_cpu(id->word70); - id->word71 = __le16_to_cpu(id->word71); - id->word72 = __le16_to_cpu(id->word72); - id->word73 = __le16_to_cpu(id->word73); - id->word74 = __le16_to_cpu(id->word74); - id->word75 = __le16_to_cpu(id->word75); - id->word76 = __le16_to_cpu(id->word76); - id->word77 = __le16_to_cpu(id->word77); - id->word78 = __le16_to_cpu(id->word78); - id->word79 = __le16_to_cpu(id->word79); - id->word80 = __le16_to_cpu(id->word80); - id->word81 = __le16_to_cpu(id->word81); - id->command_sets = __le16_to_cpu(id->command_sets); - id->word83 = __le16_to_cpu(id->word83); - id->word84 = __le16_to_cpu(id->word84); - id->word85 = __le16_to_cpu(id->word85); - id->word86 = __le16_to_cpu(id->word86); - id->word87 = __le16_to_cpu(id->word87); - id->dma_ultra = __le16_to_cpu(id->dma_ultra); - id->word89 = __le16_to_cpu(id->word89); - id->word90 = __le16_to_cpu(id->word90); - id->word91 = __le16_to_cpu(id->word91); - id->word92 = __le16_to_cpu(id->word92); - id->word93 = __le16_to_cpu(id->word93); - id->word94 = __le16_to_cpu(id->word94); - id->word95 = __le16_to_cpu(id->word95); - id->word96 = __le16_to_cpu(id->word96); - id->word97 = __le16_to_cpu(id->word97); - id->word98 = __le16_to_cpu(id->word98); - id->word99 = __le16_to_cpu(id->word99); - id->word100 = __le16_to_cpu(id->word100); - id->word101 = __le16_to_cpu(id->word101); - id->word102 = __le16_to_cpu(id->word102); - id->word103 = __le16_to_cpu(id->word103); - id->word104 = __le16_to_cpu(id->word104); - id->word105 = __le16_to_cpu(id->word105); - id->word106 = __le16_to_cpu(id->word106); - id->word107 = __le16_to_cpu(id->word107); - id->word108 = __le16_to_cpu(id->word108); - id->word109 = __le16_to_cpu(id->word109); - id->word110 = __le16_to_cpu(id->word110); - id->word111 = __le16_to_cpu(id->word111); - id->word112 = __le16_to_cpu(id->word112); - id->word113 = __le16_to_cpu(id->word113); - id->word114 = __le16_to_cpu(id->word114); - id->word115 = __le16_to_cpu(id->word115); - id->word116 = __le16_to_cpu(id->word116); - id->word117 = __le16_to_cpu(id->word117); - id->word118 = __le16_to_cpu(id->word118); - id->word119 = __le16_to_cpu(id->word119); - id->word120 = __le16_to_cpu(id->word120); - id->word121 = __le16_to_cpu(id->word121); - id->word122 = __le16_to_cpu(id->word122); - id->word123 = __le16_to_cpu(id->word123); - id->word124 = __le16_to_cpu(id->word124); - id->word125 = __le16_to_cpu(id->word125); - id->word126 = __le16_to_cpu(id->word126); - id->word127 = __le16_to_cpu(id->word127); - id->security = __le16_to_cpu(id->security); - for (i=0; i<127; i++) - id->reserved[i] = __le16_to_cpu(id->reserved[i]); - } + ppc_ide_md.fix_driveid(id); } -#undef insw -#define insw(port, buf, ns) do { \ - if ( _machine == _MACH_chrp) {\ - ide_insw((port)+_IO_BASE, (buf), (ns)); \ - }\ - else if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx) ) \ - ide_insw((port)+((_machine==_MACH_mbx)? 0x80000000: 0), \ - (buf), (ns)); \ - else \ - /* this must be the same as insw in io.h!! */ \ - _insw((unsigned short *)((port)+_IO_BASE), (buf), (ns)); \ -} while (0) -#undef outsw -/* printk("port: %x buf: %p ns: %d\n",port,buf,ns); \ */ -#define outsw(port, buf, ns) do { \ - if ( _machine == _MACH_chrp) {\ - ide_outsw((port)+_IO_BASE, (buf), (ns)); \ - }\ - else if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx) ) \ - ide_outsw((port)+((_machine==_MACH_mbx)? 0x80000000: 0), \ - (buf), (ns)); \ - else \ - /* this must be the same as outsw in io.h!! */ \ - _outsw((unsigned short *)((port)+_IO_BASE), (buf), (ns)); \ -} while (0) - #undef inb -#define inb(port) \ - in_8((unsigned char *)((port) + \ - ((_machine==_MACH_Pmac)? 0: _IO_BASE) + \ - ((_machine==_MACH_mbx)? 0x80000000: 0)) ) +#define inb(port) in_8((unsigned char *)((port) + ppc_ide_md.io_base)) #undef inb_p #define inb_p(port) inb(port) #undef outb #define outb(val, port) \ - out_8((unsigned char *)((port) + \ - ((_machine==_MACH_Pmac)? 0: _IO_BASE) + \ - ((_machine==_MACH_mbx)? 0x80000000: 0)), (val) ) + out_8((unsigned char *)((port) + ppc_ide_md.io_base), (val) ) #undef outb_p #define outb_p(val, port) outb(val, port) @@ -327,6 +150,5 @@ static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) #define ide_get_lock(lock, hdlr, data) do {} while (0) #endif /* __KERNEL__ */ -#endif /* CONFIG_APUS */ #endif /* __ASMPPC_IDE_H */ diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index b6b80c4ea..92ac97729 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -5,19 +5,9 @@ #include <asm/page.h> #include <asm/byteorder.h> -#define KERNELBASE 0xc0000000 - -/* from the Carolina Technical Spec -- Cort */ -#define IBM_ACORN 0x82A #define SIO_CONFIG_RA 0x398 #define SIO_CONFIG_RD 0x399 -#define IBM_HDD_LED 0x808 -#define IBM_EQUIP_PRESENT 0x80c -#define IBM_L2_STATUS 0x80d -#define IBM_L2_INVALIDATE 0x814 -#define IBM_SYS_CTL 0x81c - #define SLOW_DOWN_IO #define PMAC_ISA_MEM_BASE 0 @@ -26,12 +16,11 @@ #define CHRP_ISA_MEM_BASE 0xf7000000 #define CHRP_PCI_DRAM_OFFSET 0 #define PREP_ISA_IO_BASE 0x80000000 -#define PREP_ISA_MEM_BASE 0xd0000000 -/*#define PREP_ISA_MEM_BASE 0xc0000000*/ +#define PREP_ISA_MEM_BASE 0xc0000000 #define PREP_PCI_DRAM_OFFSET 0x80000000 #ifdef CONFIG_MBX -#define _IO_BASE 0 +#define _IO_BASE 0x80000000 #define _ISA_MEM_BASE 0 #define PCI_DRAM_OFFSET 0x80000000 #else /* CONFIG_MBX8xx */ @@ -58,7 +47,7 @@ extern unsigned long pci_dram_offset; #define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b)) #else #define readw(addr) in_le16((volatile unsigned short *)(addr)) -#define readl(addr) in_le32((volatile unsigned *)addr) +#define readl(addr) in_le32((volatile unsigned *)(addr)) #define writew(b,addr) out_le16((volatile unsigned short *)(addr),(b)) #define writel(b,addr) out_le32((volatile unsigned *)(addr),(b)) #endif diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index 661b2c007..3a32490b5 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -3,7 +3,10 @@ #ifndef _ASM_IRQ_H #define _ASM_IRQ_H -#include <asm/processor.h> /* for is_prep() */ +#include <asm/machdep.h> /* ppc_md */ + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); #ifndef CONFIG_8xx @@ -31,9 +34,6 @@ #define irq_to_openpic(n) ((n)-NUM_8259_INTERRUPTS) #define IRQ_8259_CASCADE NUM_8259_INTERRUPTS -extern void disable_irq(unsigned int); -extern void enable_irq(unsigned int); - #ifndef CONFIG_APUS /* * This gets called from serial.c, which is now used on @@ -42,7 +42,14 @@ extern void enable_irq(unsigned int); */ static __inline__ int irq_cannonicalize(int irq) { - return (((is_prep || is_chrp) && irq == 2) ? 9 : irq); + if (ppc_md.irq_cannonicalize) + { + return ppc_md.irq_cannonicalize(irq); + } + else + { + return irq; + } } #endif @@ -54,28 +61,26 @@ static __inline__ int irq_cannonicalize(int irq) * There are eight external interrupts (IRQs) that can be configured * as either level or edge sensitive. * On the MBX implementation, there is also the possibility of an 8259 - * through the PCI and PCI-ISA bridges. All 8259 interrupts appear - * on the 8xx as IRQ3, but I may eventually add some of the 8259 code - * back into this port to handle that controller. + * through the PCI and PCI-ISA bridges. */ -#define NR_IRQS 16 - -#define SIU_IRQ0 0 /* Highest priority */ -#define SIU_LEVEL0 1 -#define SIU_IRQ1 2 -#define SIU_LEVEL1 3 -#define SIU_IRQ2 4 -#define SIU_LEVEL2 5 -#define SIU_IRQ3 6 -#define SIU_LEVEL3 7 -#define SIU_IRQ4 8 -#define SIU_LEVEL4 9 -#define SIU_IRQ5 10 -#define SIU_LEVEL5 11 -#define SIU_IRQ6 12 -#define SIU_LEVEL6 13 -#define SIU_IRQ7 14 -#define SIU_LEVEL7 15 +#define NR_IRQS (16+16) /* 8259 has 16, too -- Cort */ + +#define SIU_IRQ0 (0+16) /* Highest priority */ +#define SIU_LEVEL0 (1+16) +#define SIU_IRQ1 (2+16) +#define SIU_LEVEL1 (3+16) +#define SIU_IRQ2 (4+16) +#define SIU_LEVEL2 (5+16) +#define SIU_IRQ3 (6+16) +#define SIU_LEVEL3 (7+16) +#define SIU_IRQ4 (8+16) +#define SIU_LEVEL4 (9+16) +#define SIU_IRQ5 (10+16) +#define SIU_LEVEL5 (11+16) +#define SIU_IRQ6 (12+16) +#define SIU_LEVEL6 (13+16) +#define SIU_IRQ7 (14+16) +#define SIU_LEVEL7 (15+16) /* The internal interrupts we can configure as we see fit. * My personal preference is CPM at level 2, which puts it above the diff --git a/include/asm-ppc/keyboard.h b/include/asm-ppc/keyboard.h index 7b40d6100..0f618fbae 100644 --- a/include/asm-ppc/keyboard.h +++ b/include/asm-ppc/keyboard.h @@ -3,7 +3,7 @@ * * Created 3 Nov 1996 by Geert Uytterhoeven * - * $Id: keyboard.h,v 1.6 1998/08/20 14:41:03 ralf Exp $ + * $Id: keyboard.h,v 1.9 1999/06/10 10:08:56 ralf Exp $ * Modified for Power Macintosh by Paul Mackerras */ @@ -21,7 +21,7 @@ #include <linux/config.h> #include <asm/adb.h> - +#include <asm/machdep.h> #ifdef CONFIG_APUS #include <asm-m68k/keyboard.h> #else @@ -30,151 +30,44 @@ #define DISABLE_KBD_DURING_INTERRUPTS 0 #define INIT_KBD -extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); -extern int mackbd_getkeycode(unsigned int scancode); -extern int mackbd_pretranslate(unsigned char scancode, char raw_mode); -extern int mackbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern int mackbd_unexpected_up(unsigned char keycode); -extern void mackbd_leds(unsigned char leds); -extern void mackbd_init_hw(void); - -extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); -extern int pckbd_getkeycode(unsigned int scancode); -extern int pckbd_pretranslate(unsigned char scancode, char raw_mode); -extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern char pckbd_unexpected_up(unsigned char keycode); -extern void pckbd_leds(unsigned char leds); -extern void pckbd_init_hw(void); - static inline int kbd_setkeycode(unsigned int scancode, unsigned int keycode) { - if ( is_prep ) - return pckbd_setkeycode(scancode,keycode); - else if ( is_chrp ) -#ifndef CONFIG_MAC_KEYBOARD - return pckbd_setkeycode(scancode,keycode); -#else - /* I'm not actually sure if it's legal to have a CHRP machine - * without an ADB controller. In any case, this should really - * be changed to be a test to see if an ADB _keyboard_ exists - * (not just a controller), but that's another story for - * another night. - */ - if ( adb_hardware == ADB_NONE ) - return pckbd_setkeycode(scancode,keycode); - else - return mackbd_setkeycode(scancode,keycode); -#endif - else - return mackbd_setkeycode(scancode,keycode); + return ppc_md.kbd_setkeycode(scancode, keycode); } -static inline int kbd_getkeycode(unsigned int x) +static inline int kbd_getkeycode(unsigned int scancode) { - if ( is_prep ) - return pckbd_getkeycode(x); - else if ( is_chrp ) -#ifndef CONFIG_MAC_KEYBOARD - return pckbd_getkeycode(x); -#else - if ( adb_hardware == ADB_NONE ) - return pckbd_getkeycode(x); - else - return mackbd_getkeycode(x); -#endif - else - return mackbd_getkeycode(x); -} - -static inline int kbd_pretranslate(unsigned char x,char y) -{ - if ( is_prep ) - return pckbd_pretranslate(x,y); - else if ( is_chrp ) -#ifndef CONFIG_MAC_KEYBOARD - return pckbd_pretranslate(x,y); -#else - if ( adb_hardware == ADB_NONE ) - return pckbd_pretranslate(x,y); - else - return mackbd_pretranslate(x,y); -#endif - else - return mackbd_pretranslate(x,y); + return ppc_md.kbd_getkeycode(scancode); } static inline int kbd_translate(unsigned char keycode, unsigned char *keycodep, - char raw_mode) + char raw_mode) { - if ( is_prep ) - return pckbd_translate(keycode,keycodep,raw_mode); - else if ( is_chrp ) -#ifndef CONFIG_MAC_KEYBOARD - return pckbd_translate(keycode,keycodep,raw_mode); -#else - if ( adb_hardware == ADB_NONE ) - return pckbd_translate(keycode,keycodep,raw_mode); - else - return mackbd_translate(keycode,keycodep,raw_mode); -#endif - else - return mackbd_translate(keycode,keycodep,raw_mode); - + return ppc_md.kbd_translate(keycode, keycodep, raw_mode); } static inline int kbd_unexpected_up(unsigned char keycode) { - if ( is_prep ) - return pckbd_unexpected_up(keycode); - else if ( is_chrp ) -#ifndef CONFIG_MAC_KEYBOARD - return pckbd_unexpected_up(keycode); -#else - if ( adb_hardware == ADB_NONE ) - return pckbd_unexpected_up(keycode); - else - return mackbd_unexpected_up(keycode); -#endif - else - return mackbd_unexpected_up(keycode); - + return ppc_md.kbd_unexpected_up(keycode); } static inline void kbd_leds(unsigned char leds) { - if ( is_prep ) - pckbd_leds(leds); - else if ( is_chrp ) -#ifndef CONFIG_MAC_KEYBOARD - pckbd_leds(leds); -#else - if ( adb_hardware == ADB_NONE ) - pckbd_leds(leds); - else - mackbd_leds(leds); -#endif - else - mackbd_leds(leds); + ppc_md.kbd_leds(leds); } static inline void kbd_init_hw(void) { - if ( is_prep ) - pckbd_init_hw(); - else if ( is_chrp ) -#ifndef CONFIG_MAC_KEYBOARD - pckbd_init_hw(); + ppc_md.kbd_init_hw(); +} + +#define kbd_sysrq_xlate (ppc_md.kbd_sysrq_xlate) + +#ifdef CONFIG_MAC_KEYBOARD +# define SYSRQ_KEY 0x69 #else - if ( adb_hardware == ADB_NONE ) - pckbd_init_hw(); - else - mackbd_init_hw(); +# define SYSRQ_KEY 0x54 #endif - else - mackbd_init_hw(); -} #endif /* CONFIG_APUS */ diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index 65d53cb38..78f35e285 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -1,3 +1,4 @@ + #ifndef _PPC_MACHDEP_H #define _PPC_MACHDEP_H @@ -7,6 +8,69 @@ #include <asm-m68k/machdep.h> #endif -#endif /* _PPC_MACHDEP_H */ +struct pt_regs; + +struct machdep_calls { + void (*setup_arch)(unsigned long * memory_start_p, + unsigned long * memory_end_p); + /* Optional, may be NULL. */ + int (*setup_residual)(char *buffer); + /* Optional, may be NULL. */ + int (*get_cpuinfo)(char *buffer); + /* Optional, may be NULL. */ + unsigned int (*irq_cannonicalize)(unsigned int irq); + void (*init_IRQ)(void); + void (*do_IRQ)(struct pt_regs *regs, int cpu, int isfake); + + /* A general init function, called by ppc_init in init/main.c. + May be NULL. */ + void (*init)(void); + + void (*restart)(char *cmd); + void (*power_off)(void); + void (*halt)(void); + + void (*time_init)(void); /* Optional, may be NULL */ + int (*set_rtc_time)(unsigned long nowtime); + unsigned long (*get_rtc_time)(void); + void (*calibrate_decr)(void); + unsigned char (*nvram_read_val)(int addr); + void (*nvram_write_val)(int addr, unsigned char val); +/* Tons of keyboard stuff. */ + int (*kbd_setkeycode)(unsigned int scancode, + unsigned int keycode); + int (*kbd_getkeycode)(unsigned int scancode); + int (*kbd_translate)(unsigned char scancode, + unsigned char *keycode, + char raw_mode); + char (*kbd_unexpected_up)(unsigned char keycode); + void (*kbd_leds)(unsigned char leds); + void (*kbd_init_hw)(void); +#ifdef CONFIG_MAGIC_SYSRQ + unsigned char *kbd_sysrq_xlate; +#endif + + /* PCI interfaces */ + int (*pcibios_read_config_byte)(unsigned char bus, + unsigned char dev_fn, unsigned char offset, unsigned char *val); + int (*pcibios_read_config_word)(unsigned char bus, + unsigned char dev_fn, unsigned char offset, unsigned short *val); + int (*pcibios_read_config_dword)(unsigned char bus, + unsigned char dev_fn, unsigned char offset, unsigned int *val); + int (*pcibios_write_config_byte)(unsigned char bus, + unsigned char dev_fn, unsigned char offset, unsigned char val); + int (*pcibios_write_config_word)(unsigned char bus, + unsigned char dev_fn, unsigned char offset, unsigned short val); + int (*pcibios_write_config_dword)(unsigned char bus, + unsigned char dev_fn, unsigned char offset, unsigned int val); + void (*pcibios_fixup)(void); +}; + +extern struct machdep_calls ppc_md; +extern char cmd_line[512]; + +extern void setup_pci_ptrs(void); + +#endif /* _PPC_MACHDEP_H */ diff --git a/include/asm-ppc/mk48t59.h b/include/asm-ppc/mk48t59.h new file mode 100644 index 000000000..4700fcdc8 --- /dev/null +++ b/include/asm-ppc/mk48t59.h @@ -0,0 +1,35 @@ +/* + * Registers for the mk48t59 real-time-clock + */ + +#ifndef _PPC_MK48T59_H +#define _PPC_MK48T59_H + +/* RTC Offsets */ + +#define MK48T59_RTC_SECONDS 0x1FF9 +#define MK48T59_RTC_MINUTES 0x1FFA +#define MK48T59_RTC_HOURS 0x1FFB +#define MK48T59_RTC_DAY_OF_WEEK 0x1FFC +#define MK48T59_RTC_DAY_OF_MONTH 0x1FFD +#define MK48T59_RTC_MONTH 0x1FFE +#define MK48T59_RTC_YEAR 0x1FFF + +#define MK48T59_RTC_CONTROLA 0x1FF8 +#define MK48T59_RTC_CA_WRITE 0x80 +#define MK48T59_RTC_CA_READ 0x40 +#define MK48T59_RTC_CA_CALIB_SIGN 0x20 +#define MK48T59_RTC_CA_CALIB_MASK 0x1f + +#define MK48T59_RTC_CONTROLB 0x1FF9 +#define MK48T59_RTC_CB_STOP 0x80 + +#ifndef BCD_TO_BIN +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#endif + +#ifndef BIN_TO_BCD +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) +#endif + +#endif /* _PPC_MK48T59_H */ diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 81ced8229..f77ef3df4 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -88,25 +88,6 @@ typedef struct _P601_BAT { P601_BATL batl; /* Lower register */ } P601_BAT; -/* Block size masks */ -#define BL_128K 0x000 -#define BL_256K 0x001 -#define BL_512K 0x003 -#define BL_1M 0x007 -#define BL_2M 0x00F -#define BL_4M 0x01F -#define BL_8M 0x03F -#define BL_16M 0x07F -#define BL_32M 0x0FF -#define BL_64M 0x1FF -#define BL_128M 0x3FF -#define BL_256M 0x7FF - -/* BAT Access Protection */ -#define BPP_XX 0x00 /* No access */ -#define BPP_RX 0x01 /* Read only */ -#define BPP_RW 0x02 /* Read/write */ - /* * Simulated two-level MMU. This structure is used by the kernel * to keep track of MMU mappings and is used to update/maintain @@ -135,6 +116,35 @@ typedef struct _MMU_context { pte **pmap; /* Two-level page-map structure */ } MMU_context; +/* invalidate a TLB entry */ +extern inline void _tlbie(unsigned long va) +{ + asm volatile ("tlbie %0" : : "r"(va)); +} + +extern void _tlbia(void); /* invalidate all TLB entries */ + +#endif /* __ASSEMBLY__ */ + +/* Block size masks */ +#define BL_128K 0x000 +#define BL_256K 0x001 +#define BL_512K 0x003 +#define BL_1M 0x007 +#define BL_2M 0x00F +#define BL_4M 0x01F +#define BL_8M 0x03F +#define BL_16M 0x07F +#define BL_32M 0x0FF +#define BL_64M 0x1FF +#define BL_128M 0x3FF +#define BL_256M 0x7FF + +/* BAT Access Protection */ +#define BPP_XX 0x00 /* No access */ +#define BPP_RX 0x01 /* Read only */ +#define BPP_RW 0x02 /* Read/write */ + /* Used to set up SDR1 register */ #define HASH_TABLE_SIZE_64K 0x00010000 #define HASH_TABLE_SIZE_128K 0x00020000 @@ -151,15 +161,6 @@ typedef struct _MMU_context { #define HASH_TABLE_MASK_2M 0x01F #define HASH_TABLE_MASK_4M 0x03F -/* invalidate a TLB entry */ -extern inline void _tlbie(unsigned long va) -{ - asm volatile ("tlbie %0" : : "r"(va)); -} - -extern void _tlbia(void); /* invalidate all TLB entries */ -#endif /* __ASSEMBLY__ */ - /* Control/status registers for the MPC8xx. * A write operation to these registers causes serialized access. * During software tablewalk, the registers used perform mask/shift-add diff --git a/include/asm-ppc/ohare.h b/include/asm-ppc/ohare.h index 094ad05b1..c022e5034 100644 --- a/include/asm-ppc/ohare.h +++ b/include/asm-ppc/ohare.h @@ -22,8 +22,8 @@ #define OH_SCC_ENABLE 0x200 #define OH_MESH_ENABLE 0x400 #define OH_FLOPPY_ENABLE 0x800 -#define OH_SCCA_IO 0x2000 -#define OH_SCCB_IO 0x4000 +#define OH_SCCA_IO 0x4000 +#define OH_SCCB_IO 0x8000 #define OH_VIA_ENABLE 0x10000 #define OH_IDECD_POWER 0x800000 diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h index 77fe08f4a..12e576e85 100644 --- a/include/asm-ppc/page.h +++ b/include/asm-ppc/page.h @@ -9,7 +9,7 @@ #define PAGE_MASK (~(PAGE_SIZE-1)) #define PAGE_OFFSET 0xc0000000 - +#define KERNELBASE PAGE_OFFSET #ifndef __ASSEMBLY__ #ifdef __KERNEL__ @@ -63,9 +63,9 @@ typedef unsigned long pgprot_t; /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - -#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +extern void clear_page(unsigned long page); #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + /* map phys->virtual and virtual->phys for RAM pages */ #ifdef CONFIG_APUS #include <asm/amigappc.h> diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 9e8e36d60..2c481490e 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -37,6 +37,7 @@ extern void flush_page_to_ram(unsigned long); extern unsigned long va_to_phys(unsigned long address); extern pte_t *va_to_pte(struct task_struct *tsk, unsigned long address); +extern unsigned long ioremap_bot, ioremap_base; #endif /* __ASSEMBLY__ */ /* * The PowerPC MMU uses a hash table containing PTEs, together with @@ -95,16 +96,19 @@ extern pte_t *va_to_pte(struct task_struct *tsk, unsigned long address); * The vmalloc() routines leaves a hole of 4kB between each vmalloced * area for the same reason. ;) * - * The vmalloc_offset MUST be larger than the gap between the bat2 mapping - * and the size of physical ram. Since the bat2 mapping can be larger than - * the amount of ram we have vmalloc_offset must ensure that we don't try - * to allocate areas that don't exist! This value of 64M will only cause - * problems when we have >128M -- Cort + * We no longer map larger than phys RAM with the BATs so we don't have + * to worry about the VMALLOC_OFFSET causing problems. We do have to worry + * about clashes between our early calls to ioremap() that start growing down + * from ioremap_base being run into the VM area allocations (growing upwards + * from VMALLOC_START). For this reason we have ioremap_bot to check when + * we actually run into our mappings setup in the early boot with the VM + * system. This really does become a problem for machines with good amounts + * of RAM. -- Cort */ -#define VMALLOC_OFFSET (0x4000000) /* 64M */ +#define VMALLOC_OFFSET (0x4000000) /* 64M */ #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))) #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END 0xf0000000 +#define VMALLOC_END ioremap_bot /* * Bits in a linux-style PTE. These match the bits in the @@ -359,47 +363,46 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } - /* * This is handled very differently on the PPC since out page tables * are all 0's and I want to be able to use these zero'd pages elsewhere * as well - it gives us quite a speedup. * - * Note that the SMP/UP versions are the same since we don't need a - * per cpu list of zero pages since we do the zero-ing with the cache + * Note that the SMP/UP versions are the same but we don't need a + * per cpu list of zero pages because we do the zero-ing with the cache * off and the access routines are lock-free but the pgt cache stuff - * _IS_ per-cpu since it isn't done with any lock-free access routines + * is per-cpu since it isn't done with any lock-free access routines * (although I think we need arch-specific routines so I can do lock-free). * * I need to generalize this so we can use it for other arch's as well. * -- Cort */ +#ifdef __SMP__ +#define quicklists cpu_data[smp_processor_id()] +#else extern struct pgtable_cache_struct { unsigned long *pgd_cache; unsigned long *pte_cache; unsigned long pgtable_cache_sz; - unsigned long *zero_cache; /* head linked list of pre-zero'd pages */ - unsigned long zero_sz; /* # currently pre-zero'd pages */ - unsigned long zeropage_hits; /* # zero'd pages request that we've done */ - unsigned long zeropage_calls; /* # zero'd pages request that've been made */ - unsigned long zerototal; /* # pages zero'd over time */ } quicklists; +#endif -#ifdef __SMP__ -/*#warning Tell Cort to do the pgt cache for SMP*/ -#define pgd_quicklist (quicklists.pgd_cache) -#define pmd_quicklist ((unsigned long *)0) -#define pte_quicklist (quicklists.pte_cache) -#define pgtable_cache_size (quicklists.pgtable_cache_sz) -#else /* __SMP__ */ -#define pgd_quicklist (quicklists.pgd_cache) -#define pmd_quicklist ((unsigned long *)0) -#define pte_quicklist (quicklists.pte_cache) -#define pgtable_cache_size (quicklists.pgtable_cache_sz) -#endif /* __SMP__ */ - -#define zero_quicklist (quicklists.zero_cache) -#define zero_cache_sz (quicklists.zero_sz) +#define pgd_quicklist (quicklists.pgd_cache) +#define pmd_quicklist ((unsigned long *)0) +#define pte_quicklist (quicklists.pte_cache) +#define pgtable_cache_size (quicklists.pgtable_cache_sz) + +extern unsigned long *zero_cache; /* head linked list of pre-zero'd pages */ +extern unsigned long zero_sz; /* # currently pre-zero'd pages */ +extern unsigned long zeropage_hits; /* # zero'd pages request that we've done */ +extern unsigned long zeropage_calls; /* # zero'd pages request that've been made */ +extern unsigned long zerototal; /* # pages zero'd over time */ + +#define zero_quicklist (zero_cache) +#define zero_cache_sz (zero_sz) +#define zero_cache_calls (zeropage_calls) +#define zero_cache_hits (zeropage_hits) +#define zero_cache_total (zerototal) /* return a pre-zero'd page from the list, return NULL if none available -- Cort */ extern unsigned long get_zero_page_fast(void); @@ -410,8 +413,8 @@ extern __inline__ pgd_t *get_pgd_slow(void) if ( (ret = (pgd_t *)get_zero_page_fast()) == NULL ) { - ret = (pgd_t *)__get_free_page(GFP_KERNEL); - memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); + if ( (ret = (pgd_t *)__get_free_page(GFP_KERNEL)) != NULL ) + memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); } if (ret) { init = pgd_offset(&init_mm, 0); @@ -553,7 +556,7 @@ extern inline void set_pgdir(unsigned long address, pgd_t entry) /* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can modify pgd caches of other CPUs as well. -jj */ for (i = 0; i < NR_CPUS; i++) - for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) + for (pgd = (pgd_t *)cpu_data[i].pgd_cache; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) pgd[address >> PGDIR_SHIFT] = entry; #endif } diff --git a/include/asm-ppc/pmu.h b/include/asm-ppc/pmu.h index ee04ae2a8..f6309d6b2 100644 --- a/include/asm-ppc/pmu.h +++ b/include/asm-ppc/pmu.h @@ -9,7 +9,7 @@ /* * PMU commands */ -#define PMU_BACKLIGHT_CTRL 0x11 /* control backlight */ +#define PMU_POWER_CTRL 0x11 /* control power of some devices */ #define PMU_ADB_CMD 0x20 /* send ADB packet */ #define PMU_ADB_POLL_OFF 0x21 /* disable ADB auto-poll */ #define PMU_WRITE_NVRAM 0x33 /* write non-volatile RAM */ @@ -29,6 +29,12 @@ #define PMU_GET_BRIGHTBUTTON 0xd9 /* report brightness up/down pos */ #define PMU_GET_COVER 0xdc /* report cover open/closed */ +/* Bits to use with the PMU_POWER_CTRL command */ +#define PMU_POW_ON 0x80 /* OR this to power ON the device */ +#define PMU_POW_OFF 0x00 /* leave bit 7 to 0 to power it OFF */ +#define PMU_POW_BACKLIGHT 0x01 /* backlight power */ +#define PMU_POW_IRLED 0x04 /* IR led power (on wallstreet) ??? */ + /* Bits in PMU interrupt and interrupt mask bytes */ #define PMU_INT_ADB_AUTO 0x04 /* ADB autopoll, when PMU_INT_ADB */ #define PMU_INT_PCEJECT 0x04 /* PC-card eject buttons */ @@ -36,27 +42,47 @@ #define PMU_INT_ADB 0x10 /* ADB autopoll or reply data */ #define PMU_INT_TICK 0x80 /* 1-second tick interrupt */ +/* Kind of PMU (model) */ +enum { + PMU_UNKNOWN, + PMU_OHARE_BASED, + PMU_HEATHROW_BASED +}; /* * Ioctl commands for the /dev/pmu device */ #include <linux/ioctl.h> +/* no param */ #define PMU_IOC_SLEEP _IO('B', 0) +/* out param: u32* backlight value: 0 to 31 */ +#define PMU_IOC_GET_BACKLIGHT _IOR('B', 1, sizeof(__u32*)) +/* in param: u32 backlight value: 0 to 31 */ +#define PMU_IOC_SET_BACKLIGHT _IOW('B', 2, sizeof(__u32)) +/* out param: u32* backlight value: 0 to 31 */ +#define PMU_IOC_GET_MODEL _IOR('B', 3, sizeof(__u32*)) #ifdef __KERNEL__ + void find_via_pmu(void); void via_pmu_init(void); + int pmu_request(struct adb_request *req, void (*done)(struct adb_request *), int nbytes, ...); -int pmu_send_request(struct adb_request *req); void pmu_poll(void); void pmu_enable_backlight(int on); +void pmu_set_brightness(int level); + +void pmu_enable_irled(int on); void pmu_restart(void); void pmu_shutdown(void); +int pmu_present(void); +int pmu_get_model(void); + /* * Stuff for putting the powerbook to sleep and waking it again. */ diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h index 479a9e8e8..893b90f70 100644 --- a/include/asm-ppc/posix_types.h +++ b/include/asm-ppc/posix_types.h @@ -43,7 +43,8 @@ typedef struct { #else /* __GNUC__ */ -#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \ + || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0) /* With GNU C, use inline functions instead so args are evaluated only once: */ #undef __FD_SET diff --git a/include/asm-ppc/prep_nvram.h b/include/asm-ppc/prep_nvram.h new file mode 100644 index 000000000..2f0f80b5c --- /dev/null +++ b/include/asm-ppc/prep_nvram.h @@ -0,0 +1,146 @@ +/* + * PreP compliant NVRAM access + */ + +/* Corey Minyard (minyard@acm.org) - Stolen from PReP book. Per the + license I must say: + (C) Copyright (Corey Minyard), (1998). All rights reserved + */ + +/* Structure map for NVRAM on PowerPC Reference Platform */ +/* All fields are either character/byte strings which are valid either + endian or they are big-endian numbers. + + There are a number of Date and Time fields which are in RTC format, + big-endian. These are stored in UT (GMT). + + For enum's: if given in hex then they are bit significant, i.e. only + one bit is on for each enum. +*/ +#ifndef _PPC_PREP_NVRAM_H +#define _PPC_PREP_NVRAM_H + +#define NVSIZE 4096 /* size of NVRAM */ +#define OSAREASIZE 512 /* size of OSArea space */ +#define CONFSIZE 1024 /* guess at size of Configuration space */ + +typedef struct _SECURITY { + unsigned long BootErrCnt; /* Count of boot password errors */ + unsigned long ConfigErrCnt; /* Count of config password errors */ + unsigned long BootErrorDT[2]; /* Date&Time from RTC of last error in pw */ + unsigned long ConfigErrorDT[2]; /* Date&Time from RTC of last error in pw */ + unsigned long BootCorrectDT[2]; /* Date&Time from RTC of last correct pw */ + unsigned long ConfigCorrectDT[2]; /* Date&Time from RTC of last correct pw */ + unsigned long BootSetDT[2]; /* Date&Time from RTC of last set of pw */ + unsigned long ConfigSetDT[2]; /* Date&Time from RTC of last set of pw */ + unsigned char Serial[16]; /* Box serial number */ +} SECURITY; + +typedef enum _OS_ID { + Unknown = 0, + Firmware = 1, + AIX = 2, + NT = 3, + MKOS2 = 4, + MKAIX = 5, + Taligent = 6, + Solaris = 7, + MK = 12 +} OS_ID; + +typedef struct _ERROR_LOG { + unsigned char ErrorLogEntry[40]; /* To be architected */ +} ERROR_LOG; + +typedef enum _BOOT_STATUS { + BootStarted = 0x01, + BootFinished = 0x02, + RestartStarted = 0x04, + RestartFinished = 0x08, + PowerFailStarted = 0x10, + PowerFailFinished = 0x20, + ProcessorReady = 0x40, + ProcessorRunning = 0x80, + ProcessorStart = 0x0100 +} BOOT_STATUS; + +typedef struct _RESTART_BLOCK { + unsigned short Version; + unsigned short Revision; + unsigned long ResumeReserve1[2]; + volatile unsigned long BootStatus; + unsigned long CheckSum; /* Checksum of RESTART_BLOCK */ + void * RestartAddress; + void * SaveAreaAddr; + unsigned long SaveAreaLength; +} RESTART_BLOCK; + +typedef enum _OSAREA_USAGE { + Empty = 0, + Used = 1 +} OSAREA_USAGE; + +typedef enum _PM_MODE { + Suspend = 0x80, /* Part of state is in memory */ + Normal = 0x00 /* No power management in effect */ +} PMMode; + +typedef struct _HEADER { + unsigned short Size; /* NVRAM size in K(1024) */ + unsigned char Version; /* Structure map different */ + unsigned char Revision; /* Structure map the same -may + be new values in old fields + in other words old code still works */ + unsigned short Crc1; /* check sum from beginning of nvram to OSArea */ + unsigned short Crc2; /* check sum of config */ + unsigned char LastOS; /* OS_ID */ + unsigned char Endian; /* B if big endian, L if little endian */ + unsigned char OSAreaUsage; /* OSAREA_USAGE */ + unsigned char PMMode; /* Shutdown mode */ + RESTART_BLOCK RestartBlock; + SECURITY Security; + ERROR_LOG ErrorLog[2]; + + /* Global Environment information */ + void * GEAddress; + unsigned long GELength; + + /* Date&Time from RTC of last change to Global Environment */ + unsigned long GELastWriteDT[2]; + + /* Configuration information */ + void * ConfigAddress; + unsigned long ConfigLength; + + /* Date&Time from RTC of last change to Configuration */ + unsigned long ConfigLastWriteDT[2]; + unsigned long ConfigCount; /* Count of entries in Configuration */ + + /* OS dependent temp area */ + void * OSAreaAddress; + unsigned long OSAreaLength; + + /* Date&Time from RTC of last change to OSAreaArea */ + unsigned long OSAreaLastWriteDT[2]; +} HEADER; + +/* Here is the whole map of the NVRAM */ +typedef struct _NVRAM_MAP { + HEADER Header; + unsigned char GEArea[NVSIZE-CONFSIZE-OSAREASIZE-sizeof(HEADER)]; + unsigned char OSArea[OSAREASIZE]; + unsigned char ConfigArea[CONFSIZE]; +} NVRAM_MAP; + +/* Routines to manipulate the NVRAM */ +void init_prep_nvram(void); +char *prep_nvram_get_var(const char *name); +char *prep_nvram_first_var(void); +char *prep_nvram_next_var(char *name); + +/* Routines to read and write directly to the NVRAM */ +unsigned char prep_nvram_read_val(int addr); +void prep_nvram_write_val(int addr, + unsigned char val); + +#endif /* _PPC_PREP_NVRAM_H */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index de8f12e5b..d3cca8a28 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -60,21 +60,36 @@ #define FPSCR_FEX (1<<30) #define _MACH_prep 1 -#define _MACH_Pmac 2 /* pmac or pmac clone (non-chrp) */ -#define _MACH_chrp 4 /* chrp machine */ -#define _MACH_mbx 8 /* Motorola MBX board */ -#define _MACH_apus 16 /* amiga with phase5 powerup */ -#define _MACH_fads 32 /* Motorola FADS board */ +#define _MACH_Pmac 2 /* pmac or pmac clone (non-chrp) */ +#define _MACH_chrp 4 /* chrp machine */ +#define _MACH_mbx 8 /* Motorola MBX board */ +#define _MACH_apus 16 /* amiga with phase5 powerup */ +#define _MACH_fads 32 /* Motorola FADS board */ +#define _MACH_rpxlite 64 /* RPCG RPX-Lite 8xx board */ +#define _MACH_bseip 128 /* Bright Star Engineering ip-Engine */ +#define _MACH_yk 256 /* Motorola Yellowknife */ /* see residual.h for these */ #define _PREP_Motorola 0x01 /* motorola prep */ #define _PREP_Firm 0x02 /* firmworks prep */ #define _PREP_IBM 0x00 /* ibm prep */ #define _PREP_Bull 0x03 /* bull prep */ +#define _PREP_Radstone 0x04 /* Radstone Technology PLC prep */ + +/* + * Radstone board types + */ +#define RS_SYS_TYPE_PPC1 0 +#define RS_SYS_TYPE_PPC2 1 +#define RS_SYS_TYPE_PPC1a 2 +#define RS_SYS_TYPE_PPC2a 3 +#define RS_SYS_TYPE_PPC4 4 +#define RS_SYS_TYPE_PPC4a 5 +#define RS_SYS_TYPE_PPC2ep 6 /* these are arbitrary */ #define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ -#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ +#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ #define _GLOBAL(n)\ .globl n;\ @@ -160,70 +175,23 @@ n: #define SR15 15 #ifndef __ASSEMBLY__ -/* - * If we've configured for a specific machine set things - * up so the compiler can optimize away the other parts. - * -- Cort - */ -#ifdef CONFIG_MACH_SPECIFIC -#ifdef CONFIG_PREP -#define _machine (_MACH_prep) -#define is_prep (1) -#define is_chrp (0) -#define have_of (0) -#endif /* CONFIG_PREP */ - -#ifdef CONFIG_CHRP -#define _machine (_MACH_chrp) -#define is_prep (0) -#define is_chrp (1) -#define have_of (1) -#endif /* CONFIG_CHRP */ - -#ifdef CONFIG_PMAC -#define _machine (_MACH_Pmac) -#define is_prep (0) -#define is_chrp (0) -#define have_of (1) -#endif /* CONFIG_PMAC */ - -#ifdef CONFIG_MBX -#define _machine (_MACH_mbx) -#define is_prep (0) -#define is_chrp (0) -#define have_of (0) -#endif /* CONFIG_MBX */ - -#ifdef CONFIG_FADS -#define _machine (_MACH_fads) -#define is_prep (0) -#define is_chrp (0) -#define have_of (0) -#endif /* CONFIG_FADS */ - -#ifdef CONFIG_APUS -#define _machine (_MACH_apus) -#define is_prep (0) -#define is_chrp (0) -#define have_of (0) -#endif /* CONFIG_APUS */ - -#else /* CONFIG_MACH_SPECIFIC */ - extern int _machine; -/* if we're a prep machine */ -#define is_prep (_machine == _MACH_prep) - -/* if we're a chrp machine */ -#define is_chrp (_machine == _MACH_chrp) - -/* if we have openfirmware */ -extern unsigned long have_of; -#endif /* CONFIG_MACH_SPECIFIC */ +/* Temporary hacks until we can clean things up better - Corey */ +extern int have_of; +extern int is_prep; +extern int is_chrp; +extern int is_powerplus; /* what kind of prep workstation we are */ extern int _prep_type; +/* + * This is used to identify the board type from a given PReP board + * vendor. Board revision is also made available. + */ +extern unsigned char ucSystemType; +extern unsigned char ucBoardRev; +extern unsigned char ucBoardRevMaj, ucBoardRevMin; struct task_struct; void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); @@ -267,7 +235,6 @@ struct thread_struct { double fpr[32]; /* Complete floating point set */ unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */ unsigned long fpscr; /* Floating point status */ - unsigned long smp_fork_ret; }; #define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack) @@ -279,7 +246,7 @@ struct thread_struct { (struct pt_regs *)INIT_SP - 1, /* regs */ \ KERNEL_DS, /*fs*/ \ 0, /* last_syscall */ \ - {0}, 0, 0, 0 \ + {0}, 0, 0 \ } /* @@ -318,6 +285,9 @@ void ll_puts(const char *); #define init_task (init_task_union.task) #define init_stack (init_task_union.stack) +/* In misc.c */ +void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); + /* * Return_address is a replacement for __builtin_return_address(count) * which on certain architectures cannot reasonably be implemented in GCC diff --git a/include/asm-ppc/raven.h b/include/asm-ppc/raven.h new file mode 100644 index 000000000..62f996f66 --- /dev/null +++ b/include/asm-ppc/raven.h @@ -0,0 +1,33 @@ +/* + * asm-ppc/raven.h -- Raven MPIC chip. + * + * Copyright (C) 1998 Johnnie Peters + * + * 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 _ASMPPC_RAVEN_H +#define _ASMPPC_RAVEN_H + +#define MVME2600_INT_SIO 0 +#define MVME2600_INT_FALCN_ECC_ERR 1 +#define MVME2600_INT_PCI_ETHERNET 2 +#define MVME2600_INT_PCI_SCSI 3 +#define MVME2600_INT_PCI_GRAPHICS 4 +#define MVME2600_INT_PCI_VME0 5 +#define MVME2600_INT_PCI_VME1 6 +#define MVME2600_INT_PCI_VME2 7 +#define MVME2600_INT_PCI_VME3 8 +#define MVME2600_INT_PCI_INTA 9 +#define MVME2600_INT_PCI_INTB 10 +#define MVME2600_INT_PCI_INTC 11 +#define MVME2600_INT_PCI_INTD 12 +#define MVME2600_INT_LM_SIG0 13 +#define MVME2600_INT_LM_SIG1 14 + +extern struct hw_interrupt_type raven_pic; + +extern int raven_init(void); +#endif _ASMPPC_RAVEN_H diff --git a/include/asm-ppc/semaphore-helper.h b/include/asm-ppc/semaphore-helper.h new file mode 100644 index 000000000..3033272d9 --- /dev/null +++ b/include/asm-ppc/semaphore-helper.h @@ -0,0 +1,107 @@ +#ifndef _PPC_SEMAPHORE_HELPER_H +#define _PPC_SEMAPHORE_HELPER_H + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + * Adapted for PowerPC by Gary Thomas and Paul Mackerras + */ + +#include <asm/atomic.h> + +/* + * These two (wake_one_more and waking_non_zero) _must_ execute + * atomically wrt each other. + * + * This is trivially done with load with reservation and + * store conditional on the ppc. + */ + +static inline void wake_one_more(struct semaphore * sem) +{ + atomic_inc(&sem->waking); +} + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret, tmp; + + /* Atomic decrement sem->waking iff it is > 0 */ + __asm__ __volatile__( + "1: lwarx %1,0,%2\n" /* tmp = sem->waking */ + " cmpwi 0,%1,0\n" /* test tmp */ + " addic %1,%1,-1\n" /* --tmp */ + " ble- 2f\n" /* exit if tmp was <= 0 */ + " stwcx. %1,0,%2\n" /* update sem->waking */ + " bne- 1b\n" /* try again if update failed*/ + " li %0,1\n" /* ret = 1 */ + "2:" + : "=r" (ret), "=&r" (tmp) + : "r" (&sem->waking), "0" (0) + : "cr0", "memory"); + + 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, tmp; + + /* Atomic decrement sem->waking iff it is > 0 */ + __asm__ __volatile__( + "1: lwarx %1,0,%2\n" /* tmp = sem->waking */ + " cmpwi 0,%1,0\n" /* test tmp */ + " addic %1,%1,-1\n" /* --tmp */ + " ble- 2f\n" /* exit if tmp was <= 0 */ + " stwcx. %1,0,%2\n" /* update sem->waking */ + " bne- 1b\n" /* try again if update failed*/ + " li %0,1\n" /* ret = 1 */ + "2:" + : "=r" (ret), "=&r" (tmp) + : "r" (&sem->waking), "0" (0) + : "cr0", "memory"); + + if (ret == 0 && signal_pending(tsk)) { + atomic_inc(&sem->count); + ret = -EINTR; + } + 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, tmp; + + /* Atomic decrement sem->waking iff it is > 0 */ + __asm__ __volatile__( + "1: lwarx %1,0,%2\n" /* tmp = sem->waking */ + " cmpwi 0,%1,0\n" /* test tmp */ + " addic %1,%1,-1\n" /* --tmp */ + " ble- 2f\n" /* exit if tmp was <= 0 */ + " stwcx. %1,0,%2\n" /* update sem->waking */ + " bne- 1b\n" /* try again if update failed*/ + " li %0,0\n" /* ret = 0 */ + "2:" + : "=r" (ret), "=&r" (tmp) + : "r" (&sem->waking), "0" (1) + : "cr0", "memory"); + + if (ret) + atomic_inc(&sem->count); + + return ret; +} + +#endif /* _PPC_SEMAPHORE_HELPER_H */ diff --git a/include/asm-ppc/semaphore.h b/include/asm-ppc/semaphore.h index a78c203d2..ab21c33a6 100644 --- a/include/asm-ppc/semaphore.h +++ b/include/asm-ppc/semaphore.h @@ -13,66 +13,54 @@ struct semaphore { atomic_t count; atomic_t waking; - struct wait_queue * wait; + struct wait_queue *wait; }; -#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) -#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) +#define sema_init(sem, val) atomic_set(&((sem)->count), (val)) + +#define MUTEX ((struct semaphore) \ + { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) \ + { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); +extern int __down_trylock(struct semaphore * sem); extern void __up(struct semaphore * sem); -#define sema_init(sem, val) atomic_set(&((sem)->count), (val)) - -/* - * These two _must_ execute atomically wrt each other. - * - * This is trivially done with load_locked/store_cond, - * i.e. load with reservation and store conditional on the ppc. - */ - -static inline void wake_one_more(struct semaphore * sem) +extern inline void down(struct semaphore * sem) { - atomic_inc(&sem->waking); + if (atomic_dec_return(&sem->count) >= 0) + wmb(); + else + __down(sem); } -static inline int waking_non_zero(struct semaphore *sem, struct task_struct *tsk) +extern inline int down_interruptible(struct semaphore * sem) { - int ret, tmp; - - __asm__ __volatile__( - "1: lwarx %1,0,%2\n" - " cmpwi 0,%1,0\n" - " addic %1,%1,-1\n" - " ble- 2f\n" - " stwcx. %1,0,%2\n" - " bne- 1b\n" - " li %0,1\n" - "2:" - : "=r" (ret), "=&r" (tmp) - : "r" (&sem->waking), "0" (0) - : "cr0", "memory"); + int ret = 0; + if (atomic_dec_return(&sem->count) >= 0) + wmb(); + else + ret = __down_interruptible(sem); return ret; } -extern inline void down(struct semaphore * sem) -{ - if (atomic_dec_return(&sem->count) < 0) - __down(sem); -} - -extern inline int down_interruptible(struct semaphore * sem) +extern inline int down_trylock(struct semaphore * sem) { int ret = 0; - if (atomic_dec_return(&sem->count) < 0) - ret = __down_interruptible(sem); + + if (atomic_dec_return(&sem->count) >= 0) + wmb(); + else + ret = __down_trylock(sem); return ret; } extern inline void up(struct semaphore * sem) { + mb(); if (atomic_inc_return(&sem->count) <= 0) __up(sem); } diff --git a/include/asm-ppc/siginfo.h b/include/asm-ppc/siginfo.h index c3a46ceff..f838fcc82 100644 --- a/include/asm-ppc/siginfo.h +++ b/include/asm-ppc/siginfo.h @@ -138,7 +138,7 @@ typedef struct siginfo { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 4fb817a8e..9186b39e5 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -6,21 +6,31 @@ #ifndef _PPC_SMP_H #define _PPC_SMP_H -#include <linux/kernel.h> /* for panic */ -#include <linux/tasks.h> /* for NR_CPUS */ +#include <linux/kernel.h> +#include <linux/tasks.h> #ifdef __SMP__ #ifndef __ASSEMBLY__ +struct cpuinfo_PPC { + unsigned long loops_per_sec; + unsigned long pvr; + unsigned long *pgd_cache; + unsigned long *pte_cache; + unsigned long pgtable_cache_sz; +}; +extern struct cpuinfo_PPC cpu_data[NR_CPUS]; + extern int first_cpu_booted; extern unsigned long smp_proc_in_lock[NR_CPUS]; extern void smp_message_pass(int target, int msg, unsigned long data, int wait); extern void smp_store_cpu_info(int id); +extern void smp_message_recv(void); #define NO_PROC_ID 0xFF /* No processor magic marker */ -#define PROC_CHANGE_PENALTY 2000 +#define PROC_CHANGE_PENALTY 20 /* 1 to 1 mapping on PPC -- Cort */ #define cpu_logical_map(cpu) (cpu) @@ -30,17 +40,6 @@ extern volatile unsigned long cpu_callin_map[NR_CPUS]; #define hard_smp_processor_id() (0) #define smp_processor_id() (current->processor) -/* per processor PPC parameters we need. */ -struct cpuinfo_PPC { - unsigned long loops_per_sec; - unsigned long pvr; - unsigned long *pgd_quick; - unsigned long *pte_quick; - unsigned long pgtable_cache_sz; -}; - -extern struct cpuinfo_PPC cpu_data[NR_CPUS]; - struct klock_info_struct { unsigned long kernel_flag; unsigned char akp; diff --git a/include/asm-ppc/softirq.h b/include/asm-ppc/softirq.h index e2064f07d..373de2356 100644 --- a/include/asm-ppc/softirq.h +++ b/include/asm-ppc/softirq.h @@ -4,7 +4,7 @@ #include <asm/atomic.h> #include <asm/hardirq.h> -extern unsigned int local_bh_count[NR_CPUS]; +extern unsigned int ppc_local_bh_count[NR_CPUS]; #define get_active_bhs() (bh_mask & bh_active) #define clear_active_bhs(x) atomic_clear_mask((x),&bh_active) @@ -18,8 +18,9 @@ extern inline void init_bh(int nr, void (*routine)(void)) extern inline void remove_bh(int nr) { - bh_base[nr] = NULL; bh_mask &= ~(1 << nr); + wmb(); + bh_base[nr] = NULL; } extern inline void mark_bh(int nr) @@ -28,6 +29,7 @@ extern inline void mark_bh(int nr) } #ifdef __SMP__ + /* * The locking mechanism for base handlers, to prevent re-entrancy, * is entirely private to an implementation, it should not be @@ -54,7 +56,7 @@ static inline int softirq_trylock(int cpu) { if (!test_and_set_bit(0,&global_bh_count)) { if (atomic_read(&global_bh_lock) == 0) { - ++local_bh_count[cpu]; + ++ppc_local_bh_count[cpu]; return 1; } clear_bit(0,&global_bh_count); @@ -64,30 +66,30 @@ static inline int softirq_trylock(int cpu) static inline void softirq_endlock(int cpu) { - local_bh_count[cpu]--; + ppc_local_bh_count[cpu]--; clear_bit(0,&global_bh_count); } -#else /* __SMP__ */ +#else extern inline void start_bh_atomic(void) { - local_bh_count[smp_processor_id()]++; + ppc_local_bh_count[smp_processor_id()]++; barrier(); } extern inline void end_bh_atomic(void) { barrier(); - local_bh_count[smp_processor_id()]--; + ppc_local_bh_count[smp_processor_id()]--; } /* These are for the irq's testing the lock */ -#define softirq_trylock(cpu) (local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1)) -#define softirq_endlock(cpu) (local_bh_count[cpu] = 0) -#define synchronize_bh() do { } while (0) +#define softirq_trylock(cpu) (ppc_local_bh_count[cpu] ? 0 : (ppc_local_bh_count[cpu]=1)) +#define softirq_endlock(cpu) (ppc_local_bh_count[cpu] = 0) +#define synchronize_bh() barrier() -#endif /* __SMP__ */ +#endif /* SMP */ /* * These use a mask count to correctly handle @@ -106,4 +108,4 @@ extern inline void enable_bh(int nr) bh_mask |= 1 << nr; } -#endif +#endif /* __ASM_SOFTIRQ_H */ diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h index c048dbc1a..afaf5ebb3 100644 --- a/include/asm-ppc/spinlock.h +++ b/include/asm-ppc/spinlock.h @@ -102,6 +102,8 @@ extern int spin_trylock(spinlock_t *lock); #define spin_unlock_irqrestore(lock, flags) \ do { spin_unlock(lock); __restore_flags(flags); } while (0) +extern unsigned long __spin_trylock(volatile unsigned long *lock); + /* * Read-write spinlocks, allowing multiple readers * but only one writer. diff --git a/include/asm-ppc/string.h b/include/asm-ppc/string.h index 1af5e6270..e0158a215 100644 --- a/include/asm-ppc/string.h +++ b/include/asm-ppc/string.h @@ -14,5 +14,6 @@ #define __HAVE_ARCH_MEMCHR extern int strcasecmp(const char *, const char *); +extern int strncasecmp(const char *, const char *, int); #endif diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 5a1740847..427bb5ddd 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -9,38 +9,42 @@ * Memory barrier. * The sync instruction guarantees that all memory accesses initiated * by this processor have been performed (with respect to all other - * mechanisms that access memory). + * mechanisms that access memory). The eieio instruction is a barrier + * providing an ordering (separately) for (a) cacheable stores and (b) + * loads and stores to non-cacheable memory (e.g. I/O devices). + * + * mb() prevents loads and stores being reordered across this point. + * rmb() prevents loads being reordered across this point. + * wmb() prevents stores being reordered across this point. + * + * We can use the eieio instruction for wmb, but since it doesn't + * give any ordering guarantees about loads, we have to use the + * stronger but slower sync instruction for mb and rmb. */ #define mb() __asm__ __volatile__ ("sync" : : : "memory") #define rmb() __asm__ __volatile__ ("sync" : : : "memory") -#define wmb() __asm__ __volatile__ ("sync" : : : "memory") +#define wmb() __asm__ __volatile__ ("eieio" : : : "memory") + +extern void xmon_irq(int, void *, struct pt_regs *); +extern void xmon(struct pt_regs *excp); #define __save_flags(flags) ({\ __asm__ __volatile__ ("mfmsr %0" : "=r" ((flags)) : : "memory"); }) #define __save_and_cli(flags) ({__save_flags(flags);__cli();}) +/* Data cache block flush - write out the cache line containing the + specified address and then invalidate it in the cache. */ extern __inline__ void dcbf(void *line) { - asm("dcbf %0,%1\n\t" - "sync \n\t" - "isync \n\t" - :: "r" (line), "r" (0)); + asm("dcbf %0,%1; sync" : : "r" (line), "r" (0)); } -extern __inline__ void dcbi(void *line) -{ - asm("dcbi %0,%1\n\t" - "sync \n\t" - "isync \n\t" - :: "r" (line), "r" (0)); -} - extern __inline__ void __restore_flags(unsigned long flags) { - extern atomic_t n_lost_interrupts; + extern atomic_t ppc_n_lost_interrupts; extern void do_lost_interrupts(unsigned long); - if ((flags & MSR_EE) && atomic_read(&n_lost_interrupts) != 0) { + if ((flags & MSR_EE) && atomic_read(&ppc_n_lost_interrupts) != 0) { do_lost_interrupts(flags); } else { __asm__ __volatile__ ("sync; mtmsr %0; isync" @@ -54,6 +58,7 @@ extern void __cli(void); extern int _disable_interrupts(void); extern void _enable_interrupts(int); +extern void instruction_dump(unsigned long *); extern void print_backtrace(unsigned long *); extern void show_regs(struct pt_regs * regs); extern void flush_instruction_cache(void); @@ -66,8 +71,8 @@ extern void via_cuda_init(void); extern void pmac_nvram_init(void); extern void read_rtc_time(void); extern void pmac_find_display(void); -extern void giveup_fpu(void); -extern void smp_giveup_fpu(struct task_struct *); +extern void giveup_fpu(struct task_struct *); +extern void enable_kernel_fp(void); extern void cvt_fd(float *from, double *to, unsigned long *fpscr); extern void cvt_df(double *from, float *to, unsigned long *fpscr); @@ -75,11 +80,14 @@ struct device_node; extern void note_scsi_host(struct device_node *, void *); struct task_struct; -extern void switch_to(struct task_struct *prev, struct task_struct *next); +#define switch_to(prev,next,last) _switch_to((prev),(next),&(last)) +extern void _switch_to(struct task_struct *, struct task_struct *, + struct task_struct **); struct thread_struct; -extern void _switch(struct thread_struct *prev, struct thread_struct *next, - unsigned long context); +extern struct task_struct *_switch(struct thread_struct *prev, + struct thread_struct *next, + unsigned long context); struct pt_regs; extern void dump_regs(struct pt_regs *); @@ -107,8 +115,8 @@ extern void __global_restore_flags(unsigned long); #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) -extern void *xchg_u64(void *ptr, unsigned long val); -extern void *xchg_u32(void *m, unsigned long val); +extern unsigned long xchg_u64(void *ptr, unsigned long val); +extern unsigned long xchg_u32(void *ptr, unsigned long val); /* * This function doesn't exist, so you'll get a linker error @@ -126,10 +134,10 @@ extern void __xchg_called_with_bad_pointer(void); static inline unsigned long __xchg(unsigned long x, void * ptr, int size) { switch (size) { - case 4: - return (unsigned long )xchg_u32(ptr, x); - case 8: - return (unsigned long )xchg_u64(ptr, x); + case 4: + return (unsigned long )xchg_u32(ptr, x); + case 8: + return (unsigned long )xchg_u64(ptr, x); } __xchg_called_with_bad_pointer(); return x; diff --git a/include/asm-ppc/termbits.h b/include/asm-ppc/termbits.h index 0d387ca10..11b4c513a 100644 --- a/include/asm-ppc/termbits.h +++ b/include/asm-ppc/termbits.h @@ -121,7 +121,7 @@ struct termios { #define B38400 0000017 #define EXTA B19200 #define EXTB B38400 -#define CBAUDEX 0000020 +#define CBAUDEX 0000000 #define B57600 00020 #define B115200 00021 #define B230400 00022 diff --git a/include/asm-ppc/termios.h b/include/asm-ppc/termios.h index 13b3591b8..a234aff15 100644 --- a/include/asm-ppc/termios.h +++ b/include/asm-ppc/termios.h @@ -184,6 +184,7 @@ struct termio { #define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */ #define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ #ifdef __KERNEL__ diff --git a/include/asm-ppc/types.h b/include/asm-ppc/types.h index 6f95c17e6..86fa349d3 100644 --- a/include/asm-ppc/types.h +++ b/include/asm-ppc/types.h @@ -6,6 +6,8 @@ * header files exported to user space */ +typedef unsigned short umode_t; + typedef __signed__ char __s8; typedef unsigned char __u8; @@ -25,8 +27,6 @@ typedef unsigned long long __u64; */ #ifdef __KERNEL__ -typedef unsigned short umode_t; - typedef signed char s8; typedef unsigned char u8; diff --git a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h index b22b81511..59956966a 100644 --- a/include/asm-ppc/uaccess.h +++ b/include/asm-ppc/uaccess.h @@ -27,7 +27,7 @@ #define segment_eq(a,b) ((a).seg == (b).seg) #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) -#define __user_ok(addr,size) (((size) <= 0x80000000)&&((addr) <= 0x80000000-(size))) +#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) @@ -224,6 +224,10 @@ copy_to_user(void *to, const void *from, unsigned long n) return n; } +#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) + +#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; }) + #define __copy_from_user(to, from, size) \ __copy_tofrom_user((to), (from), (size)) #define __copy_to_user(to, from, size) \ diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h index 5e8c3910e..bc96d7fef 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-ppc/unistd.h @@ -193,6 +193,7 @@ #define __NR_sendfile 186 #define __NR_getpmsg 187 /* some people actually want streams */ #define __NR_putpmsg 188 /* some people actually want streams */ +#define __NR_vfork 189 #define __NR(n) #n diff --git a/include/asm-ppc/vga.h b/include/asm-ppc/vga.h index 1ab739772..85c9ec8a9 100644 --- a/include/asm-ppc/vga.h +++ b/include/asm-ppc/vga.h @@ -8,24 +8,46 @@ #define _LINUX_ASM_VGA_H_ #include <asm/io.h> +#include <asm/processor.h> + +#include <linux/config.h> +#include <linux/console.h> #define VT_BUF_HAVE_RW extern inline void scr_writew(u16 val, u16 *addr) { - st_le16(addr, val); + /* If using vgacon (not fbcon) byteswap the writes. + * If non-vgacon assume fbcon and don't byteswap + * just like include/linux/vt_buffer.h. + * XXX: this is a performance loss so get rid of it + * as soon as fbcon works on prep. + * -- Cort + */ +#ifdef CONFIG_FB + if ( conswitchp != &vga_con ) + (*(addr) = (val)); + else +#endif /* CONFIG_FB */ + st_le16(addr, val); } -extern inline u16 scr_readw(u16 *addr) +extern inline u16 scr_readw(const u16 *addr) { - return ld_le16(addr); +#ifdef CONFIG_FB + if ( conswitchp != &vga_con ) + return (*(addr)); + else +#endif /* CONFIG_FB */ + return ld_le16((unsigned short *)addr); } #define VT_BUF_HAVE_MEMCPYF #define scr_memcpyw_from memcpy #define scr_memcpyw_to memcpy -#define VGA_MAP_MEM(x) (x + _ISA_MEM_BASE) +extern unsigned long vgacon_remap_base; +#define VGA_MAP_MEM(x) (x + vgacon_remap_base) #define vga_readb(x) (*(x)) #define vga_writeb(x,y) (*(y) = (x)) |