diff options
Diffstat (limited to 'include/asm-i386')
-rw-r--r-- | include/asm-i386/bitops.h | 38 | ||||
-rw-r--r-- | include/asm-i386/current.h | 16 | ||||
-rw-r--r-- | include/asm-i386/delay.h | 17 | ||||
-rw-r--r-- | include/asm-i386/hardirq.h | 1 | ||||
-rw-r--r-- | include/asm-i386/keyboard.h | 40 | ||||
-rw-r--r-- | include/asm-i386/processor.h | 22 | ||||
-rw-r--r-- | include/asm-i386/semaphore.h | 46 | ||||
-rw-r--r-- | include/asm-i386/smp.h | 8 | ||||
-rw-r--r-- | include/asm-i386/smp_lock.h | 17 | ||||
-rw-r--r-- | include/asm-i386/spinlock.h | 66 | ||||
-rw-r--r-- | include/asm-i386/system.h | 4 |
11 files changed, 155 insertions, 120 deletions
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h index 8e6d484e4..ee24aa79f 100644 --- a/include/asm-i386/bitops.h +++ b/include/asm-i386/bitops.h @@ -26,7 +26,31 @@ struct __dummy { unsigned long a[100]; }; #define ADDR (*(struct __dummy *) addr) #define CONST_ADDR (*(const struct __dummy *) addr) -extern __inline__ int set_bit(int nr, volatile void * addr) +extern __inline__ void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"ir" (nr)); +} + +extern __inline__ void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"ir" (nr)); +} + +extern __inline__ void change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btcl %1,%0" + :"=m" (ADDR) + :"ir" (nr)); +} + +extern __inline__ int test_and_set_bit(int nr, volatile void * addr) { int oldbit; @@ -37,7 +61,7 @@ extern __inline__ int set_bit(int nr, volatile void * addr) return oldbit; } -extern __inline__ int clear_bit(int nr, volatile void * addr) +extern __inline__ int test_and_clear_bit(int nr, volatile void * addr) { int oldbit; @@ -48,7 +72,7 @@ extern __inline__ int clear_bit(int nr, volatile void * addr) return oldbit; } -extern __inline__ int change_bit(int nr, volatile void * addr) +extern __inline__ int test_and_change_bit(int nr, volatile void * addr) { int oldbit; @@ -150,15 +174,15 @@ extern __inline__ unsigned long ffz(unsigned long word) #ifdef __KERNEL__ -#define ext2_set_bit set_bit -#define ext2_clear_bit clear_bit +#define ext2_set_bit test_and_set_bit +#define ext2_clear_bit test_and_clear_bit #define ext2_test_bit test_bit #define ext2_find_first_zero_bit find_first_zero_bit #define ext2_find_next_zero_bit find_next_zero_bit /* Bitmap functions for the minix filesystem. */ -#define minix_set_bit(nr,addr) set_bit(nr,addr) -#define minix_clear_bit(nr,addr) clear_bit(nr,addr) +#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr) +#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr) #define minix_test_bit(nr,addr) test_bit(nr,addr) #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) diff --git a/include/asm-i386/current.h b/include/asm-i386/current.h index 01ba3e9a0..976320d75 100644 --- a/include/asm-i386/current.h +++ b/include/asm-i386/current.h @@ -1,12 +1,14 @@ #ifndef _I386_CURRENT_H #define _I386_CURRENT_H -/* Some architectures may want to do something "clever" here since - * this is the most frequently accessed piece of data in the entire - * kernel. For an example, see the Sparc implementation where an - * entire register is hard locked to contain the value of current. - */ -extern struct task_struct *current_set[NR_CPUS]; -#define current (current_set[smp_processor_id()]) /* Current on this processor */ +static inline unsigned long get_esp(void) +{ + unsigned long esp; + __asm__("movl %%esp,%0":"=r" (esp)); + return esp; +} + +#define current ((struct task_struct *)(get_esp() & ~8191UL)) + #endif /* !(_I386_CURRENT_H) */ diff --git a/include/asm-i386/delay.h b/include/asm-i386/delay.h index e22e8d6b2..3435e4d1b 100644 --- a/include/asm-i386/delay.h +++ b/include/asm-i386/delay.h @@ -30,21 +30,26 @@ extern __inline__ void __delay(int loops) * first constant multiplications gets optimized away if the delay is * a constant) */ -extern __inline__ void udelay(unsigned long usecs) +extern __inline__ void __udelay(unsigned long usecs, unsigned long lps) { usecs *= 0x000010c6; /* 2**32 / 1000000 */ __asm__("mull %0" :"=d" (usecs) -#ifdef __SMP__ - :"a" (usecs),"0" (cpu_data[smp_processor_id()].udelay_val) -#else - :"a" (usecs),"0" (loops_per_sec) -#endif + :"a" (usecs),"0" (lps) :"ax"); __delay(usecs); } +#ifdef __SMP__ +#define __udelay_val cpu_data[smp_processor_id()].udelay_val +#else +#define __udelay_val loops_per_sec +#endif + +#define udelay(usecs) __udelay((usecs),__udelay_val) + + extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) { __asm__("mull %1 ; divl %2" diff --git a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h index bdaad9b35..0ceef9108 100644 --- a/include/asm-i386/hardirq.h +++ b/include/asm-i386/hardirq.h @@ -58,7 +58,6 @@ static inline int hardirq_trylock(int cpu) return 0; } ++local_irq_count[cpu]; - __sti(); return 1; } diff --git a/include/asm-i386/keyboard.h b/include/asm-i386/keyboard.h index ed6c7d472..180d747e5 100644 --- a/include/asm-i386/keyboard.h +++ b/include/asm-i386/keyboard.h @@ -1,18 +1,43 @@ /* - * CPU specific parts of the keyboard driver + * linux/include/asm-i386/keyboard.h * - * 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 3 Nov 1996 by Geert Uytterhoeven */ -#ifndef __ASM_i386_KEYBOARD_H -#define __ASM_i386_KEYBOARD_H + +/* + * This file contains the i386 architecture specific keyboard definitions + */ + +#ifndef _I386_KEYBOARD_H +#define _I386_KEYBOARD_H + +#ifdef __KERNEL__ #include <asm/io.h> -#define KEYBOARD_IRQ 1 +#define KEYBOARD_IRQ 1 +#define DISABLE_KBD_DURING_INTERRUPTS 0 #define KBD_REPORT_ERR +#define KBD_REPORT_UNKN +/* #define KBD_IS_FOCUS_9000 */ + +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); + +#define kbd_setkeycode pckbd_setkeycode +#define kbd_getkeycode pckbd_getkeycode +#define kbd_pretranslate pckbd_pretranslate +#define kbd_translate pckbd_translate +#define kbd_unexpected_up pckbd_unexpected_up +#define kbd_leds pckbd_leds +#define kbd_init_hw pckbd_init_hw #define kbd_inb_p(port) inb_p(port) #define kbd_inb(port) inb(port) @@ -25,4 +50,5 @@ keyboard_setup() request_region(0x60,16,"keyboard"); } +#endif /* __KERNEL__ */ #endif /* __ASM_i386_KEYBOARD_H */ diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 9c6830f68..b4f26c73c 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -119,14 +119,15 @@ struct thread_struct { /* virtual 86 mode info */ struct vm86_struct * vm86_info; unsigned long screen_bitmap; - unsigned long v86flags, v86mask, v86mode; + unsigned long v86flags, v86mask, v86mode, saved_esp0; }; -#define INIT_MMAP { &init_mm, 0xC0000000, 0xFFFFF000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } +#define INIT_MMAP \ +{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } #define INIT_TSS { \ 0,0, \ - sizeof(init_kernel_stack) + (long) &init_kernel_stack, \ + sizeof(init_stack) + (long) &init_stack, \ KERNEL_DS, 0, \ 0,0,0,0,0,0, \ (long) &swapper_pg_dir - PAGE_OFFSET, \ @@ -137,7 +138,7 @@ struct thread_struct { {~0, }, /* ioperm */ \ _TSS(0), 0, 0, 0, KERNEL_DS, \ { { 0, }, }, /* 387 state */ \ - NULL, 0, 0, 0, 0 /* vm86_info */, \ + NULL, 0, 0, 0, 0, 0 /* vm86_info */, \ } #define start_thread(regs, new_eip, new_esp) do {\ @@ -164,10 +165,15 @@ extern inline unsigned long thread_saved_pc(struct thread_struct *t) } /* Allocation and freeing of basic task resources. */ -#define alloc_task_struct() kmalloc(sizeof(struct task_struct), GFP_KERNEL) -#define alloc_kernel_stack(p) __get_free_page(GFP_KERNEL) -#define free_task_struct(p) kfree(p) -#define free_kernel_stack(page) free_page((page)) +/* + * NOTE! The task struct and the stack go together + */ +#define alloc_task_struct() \ + ((struct task_struct *) __get_free_pages(GFP_KERNEL,1,0)) +#define free_task_struct(p) free_pages((unsigned long)(p),1) + +#define init_task (init_task_union.task) +#define init_stack (init_task_union.stack) /* * Return_address is a replacement for __builtin_return_address(count) diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h index 4395dfce0..3ba3f8af5 100644 --- a/include/asm-i386/semaphore.h +++ b/include/asm-i386/semaphore.h @@ -85,44 +85,45 @@ extern inline void down(struct semaphore * sem) { __asm__ __volatile__( "# atomic down operation\n\t" - "movl $1f,%%eax\n\t" #ifdef __SMP__ "lock ; " #endif "decl 0(%0)\n\t" - "js " SYMBOL_NAME_STR(__down_failed) - "\n1:" + "js 2f\n" + "1:\n" + ".section .text.lock,\"ax\"\n" + "2:\tpushl $1b\n\t" + "jmp __down_failed\n" + ".previous" :/* no outputs */ :"c" (sem) - :"ax","memory"); + :"memory"); } -/* - * This version waits in interruptible state so that the waiting - * process can be killed. The down_failed_interruptible routine - * returns negative for signalled and zero for semaphore acquired. - */ extern inline int down_interruptible(struct semaphore * sem) { - int ret; + int result; __asm__ __volatile__( "# atomic interruptible down operation\n\t" - "movl $1f,%0\n\t" #ifdef __SMP__ "lock ; " #endif "decl 0(%1)\n\t" - "js " SYMBOL_NAME_STR(__down_failed_interruptible) "\n\t" - "xorl %0,%0" - "\n1:" - :"=a" (ret) + "js 2f\n\t" + "xorl %0,%0\n" + "1:\n" + ".section .text.lock,\"ax\"\n" + "2:\tpushl $1b\n\t" + "jmp __down_failed_interruptible\n" + ".previous" + :"=a" (result) :"c" (sem) :"memory"); - - return ret; + return result; } + /* * Note! This is subtle. We jump to wake people up only if * the semaphore was negative (== somebody was waiting on it). @@ -133,16 +134,19 @@ extern inline void up(struct semaphore * sem) { __asm__ __volatile__( "# atomic up operation\n\t" - "movl $1f,%%eax\n\t" #ifdef __SMP__ "lock ; " #endif "incl 0(%0)\n\t" - "jle " SYMBOL_NAME_STR(__up_wakeup) - "\n1:" + "jle 2f\n" + "1:\n" + ".section .text.lock,\"ax\"\n" + "2:\tpushl $1b\n\t" + "jmp __up_wakeup\n" + ".previous" :/* no outputs */ :"c" (sem) - :"ax", "memory"); + :"memory"); } #endif diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index f1d977f22..0f7ae1224 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -178,7 +178,6 @@ extern int smp_found_config; extern int smp_scan_config(unsigned long, unsigned long); extern unsigned long smp_alloc_memory(unsigned long mem_base); extern unsigned char *apic_reg; -extern unsigned char *kernel_stacks[NR_CPUS]; extern unsigned char boot_cpu_id; extern unsigned long cpu_present_map; extern volatile int cpu_number_map[NR_CPUS]; @@ -192,6 +191,9 @@ extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); extern void smp_reschedule_irq(int cpl, struct pt_regs *regs); extern unsigned long ipi_count; extern void smp_invalidate_rcv(void); /* Process an NMI */ +extern void smp_local_timer_interrupt(struct pt_regs * regs); +extern void setup_APIC_clock (void); + /* * General functions that each host system must provide. @@ -228,7 +230,9 @@ extern __inline unsigned long apic_read(unsigned long reg) * the apic we get the right answer). Hopefully other processors are more sensible 8) */ -extern __inline int smp_processor_id(void) +#define smp_processor_id() (current->processor) + +extern __inline int hard_smp_processor_id(void) { /* we don't want to mark this access volatile - bad code generation */ return GET_APIC_ID(*(unsigned long *)(apic_reg+APIC_ID)); diff --git a/include/asm-i386/smp_lock.h b/include/asm-i386/smp_lock.h index 160e3562d..4f78f97fb 100644 --- a/include/asm-i386/smp_lock.h +++ b/include/asm-i386/smp_lock.h @@ -31,14 +31,11 @@ do { \ #define reacquire_kernel_lock(task, cpu, depth) \ do { if (depth) __asm__ __volatile__( \ "cli\n\t" \ - "movl $0f,%%eax\n\t" \ - "jmp __lock_kernel\n" \ - "0:\t" \ + "call __lock_kernel\n\t" \ "movl %2,%0\n\t" \ "sti" \ : "=m" (task->lock_depth) \ - : "d" (cpu), "c" (depth) \ - : "ax"); \ + : "d" (cpu), "c" (depth)); \ } while (0) @@ -62,14 +59,12 @@ l2: printk("Ugh at %p\n", &&l2); cli cmpl $0, %0 jne 0f - movl $0f, %%eax - jmp __lock_kernel -0: - incl %0 + call __lock_kernel +0: incl %0 popfl " : - : "m" (current_set[cpu]->lock_depth), "d" (cpu) - : "ax", "memory"); + : "m" (current->lock_depth), "d" (cpu) + : "memory"); } extern __inline__ void unlock_kernel(void) diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index 27630b21d..af6cf8c9c 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -77,13 +77,15 @@ typedef struct { unsigned long a[100]; } __dummy_lock_t; #define spin_lock(lock) \ __asm__ __volatile__( \ - "jmp 2f\n" \ - "1:\t" \ - "testb $1,%0\n\t" \ - "jne 1b\n" \ - "2:\t" \ + "\n1:\t" \ "lock ; btsl $0,%0\n\t" \ - "jc 1b" \ + "jc 2f\n" \ + ".section .text.lock,\"ax\"\n" \ + "2:\t" \ + "testb $1,%0\n\t" \ + "jne 2b\n\t" \ + "jmp 1b\n" \ + ".previous" \ :"=m" (__dummy_lock(lock))) #define spin_unlock(lock) \ @@ -91,33 +93,7 @@ __asm__ __volatile__( \ "lock ; btrl $0,%0" \ :"=m" (__dummy_lock(lock))) -#undef spin_lock -static inline void spin_lock(spinlock_t * lock) -{ - __label__ l1; - int stuck = 10000000; -l1: - __asm__ __volatile__( - "jmp 2f\n" - "1:\t" - "decl %1\n\t" - "je 3f\n\t" - "testb $1,%0\n\t" - "jne 1b\n" - "2:\t" - "lock ; btsl $0,%0\n\t" - "jc 1b\n" - "3:" - :"=m" (__dummy_lock(lock)), - "=r" (stuck) - :"1" (stuck)); - if (!stuck) { - printk("spinlock stuck at %p (%lx)\n",&&l1,lock->previous); - } else - lock->previous = (unsigned long) &&l1; -} - -#define spin_trylock(lock) (!set_bit(0,(lock))) +#define spin_trylock(lock) (!test_and_set_bit(0,(lock))) #define spin_lock_irq(lock) \ do { __cli(); spin_lock(lock); } while (0) @@ -158,12 +134,12 @@ typedef struct { asm volatile("\n1:\t" \ "lock ; incl %0\n\t" \ "js 2f\n" \ - ".text 2\n" \ + ".section .text.lock,\"ax\"\n" \ "2:\tlock ; decl %0\n" \ "3:\tcmpl $0,%0\n\t" \ "js 3b\n\t" \ "jmp 1b\n" \ - ".text" \ + ".previous" \ :"=m" (__dummy_lock(&(rw)->lock))) #define read_unlock(rw) \ @@ -173,19 +149,15 @@ typedef struct { #define write_lock(rw) \ asm volatile("\n1:\t" \ "lock ; btsl $31,%0\n\t" \ - "jc 3f\n\t" \ - "testl $0x7fffffff,%0\n\t" \ - "jne 4f\n" \ - "2:\n" \ - ".text 2\n" \ - "3:\ttestl $-1,%0\n\t" \ - "js 3b\n\t" \ - "lock ; btsl $31,%0\n\t" \ - "jc 3b\n" \ - "4:\ttestl $0x7fffffff,%0\n\t" \ + "jc 4f\n" \ + "2:\ttestl $0x7fffffff,%0\n\t" \ + "jne 3f\n" \ + ".section .text.lock,\"ax\"\n" \ + "3:\tlock ; btrl $31,%0\n" \ + "4:\tcmp $0,%0\n\t" \ "jne 4b\n\t" \ - "jmp 2b\n" \ - ".text" \ + "jmp 1b\n" \ + ".previous" \ :"=m" (__dummy_lock(&(rw)->lock))) #define write_unlock(rw) \ diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index a3daf450d..94e01ec2a 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h @@ -73,7 +73,6 @@ __asm__("str %%ax\n\t" \ __asm__ __volatile__("fwait"); \ prev->flags&=~PF_USEDFPU; \ } \ - current_set[this_cpu] = next; \ __asm__("ljmp %0\n\t" \ : /* no output */ \ :"m" (*(((char *)&next->tss.tr)-4)), \ @@ -91,8 +90,7 @@ __asm__("ljmp %0\n\t" \ #else #define switch_to(prev,next) do { \ -__asm__("movl %2,"SYMBOL_NAME_STR(current_set)"\n\t" \ - "ljmp %0\n\t" \ +__asm__("ljmp %0\n\t" \ "cmpl %1,"SYMBOL_NAME_STR(last_task_used_math)"\n\t" \ "jne 1f\n\t" \ "clts\n" \ |