/branches/network/kernel/arch/ia32/include/atomic.h |
---|
41,17 → 41,17 |
static inline void atomic_inc(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ("lock incl %0\n" : "=m" (val->count)); |
asm volatile ("lock incl %0\n" : "+m" (val->count)); |
#else |
asm volatile ("incl %0\n" : "=m" (val->count)); |
asm volatile ("incl %0\n" : "+m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
static inline void atomic_dec(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ("lock decl %0\n" : "=m" (val->count)); |
asm volatile ("lock decl %0\n" : "+m" (val->count)); |
#else |
asm volatile ("decl %0\n" : "=m" (val->count)); |
asm volatile ("decl %0\n" : "+m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
61,7 → 61,7 |
asm volatile ( |
"lock xaddl %1, %0\n" |
: "=m" (val->count), "+r" (r) |
: "+m" (val->count), "+r" (r) |
); |
return r; |
73,14 → 73,14 |
asm volatile ( |
"lock xaddl %1, %0\n" |
: "=m" (val->count), "+r"(r) |
: "+m" (val->count), "+r"(r) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val)+1) |
#define atomic_predec(val) (atomic_postdec(val)-1) |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
static inline uint32_t test_and_set(atomic_t *val) { |
uint32_t v; |
88,7 → 88,7 |
asm volatile ( |
"movl $1, %0\n" |
"xchgl %0, %1\n" |
: "=r" (v),"=m" (val->count) |
: "=r" (v),"+m" (val->count) |
); |
return v; |
101,20 → 101,20 |
preemption_disable(); |
asm volatile ( |
"0:;" |
"0:\n" |
#ifdef CONFIG_HT |
"pause;" /* Pentium 4's HT love this instruction */ |
"pause\n" /* Pentium 4's HT love this instruction */ |
#endif |
"mov %0, %1;" |
"testl %1, %1;" |
"jnz 0b;" /* Lightweight looping on locked spinlock */ |
"mov %0, %1\n" |
"testl %1, %1\n" |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"incl %1;" /* now use the atomic operation */ |
"xchgl %0, %1;" |
"testl %1, %1;" |
"jnz 0b;" |
: "=m"(val->count),"=r"(tmp) |
); |
"incl %1\n" /* now use the atomic operation */ |
"xchgl %0, %1\n" |
"testl %1, %1\n" |
"jnz 0b\n" |
: "+m" (val->count), "=&r"(tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
*/ |
/branches/network/kernel/arch/ia32/include/mm/page.h |
---|
40,8 → 40,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
128,6 → 126,8 |
#include <mm/mm.h> |
#include <arch/interrupt.h> |
#include <arch/types.h> |
#include <typedefs.h> |
/* Page fault error codes. */ |
/branches/network/kernel/arch/ia32/include/barrier.h |
---|
84,6 → 84,15 |
# endif |
#endif |
/* |
* On ia32, the hardware takes care about instruction and data cache coherence, |
* even on SMP systems. We issue a write barrier to be sure that writes |
* queueing in the store buffer drain to the memory (even though it would be |
* sufficient for them to drain to the D-cache). |
*/ |
#define smc_coherence(a) write_barrier() |
#define smc_coherence_block(a, l) write_barrier() |
#endif |
/** @} |
/branches/network/kernel/arch/ia32/include/memstr.h |
---|
35,116 → 35,13 |
#ifndef KERN_ia32_MEMSTR_H_ |
#define KERN_ia32_MEMSTR_H_ |
/** Copy memory |
* |
* Copy a given number of bytes (3rd argument) |
* from the memory location defined by 2nd argument |
* to the memory location defined by 1st argument. |
* The memory areas cannot overlap. |
* |
* @param dst Destination |
* @param src Source |
* @param cnt Number of bytes |
* @return Destination |
*/ |
static inline void * memcpy(void * dst, const void * src, size_t cnt) |
{ |
unative_t d0, d1, d2; |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
asm volatile( |
/* copy all full dwords */ |
"rep movsl\n\t" |
/* load count again */ |
"movl %4, %%ecx\n\t" |
/* ecx = ecx mod 4 */ |
"andl $3, %%ecx\n\t" |
/* are there last <=3 bytes? */ |
"jz 1f\n\t" |
/* copy last <=3 bytes */ |
"rep movsb\n\t" |
/* exit from asm block */ |
"1:\n" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
: "0" ((unative_t) (cnt / 4)), "g" ((unative_t) cnt), "1" ((unative_t) dst), "2" ((unative_t) src) |
: "memory"); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
return dst; |
} |
extern int memcmp(const void *a, const void *b, size_t cnt); |
/** Compare memory regions for equality |
* |
* Compare a given number of bytes (3rd argument) |
* at memory locations defined by 1st and 2nd argument |
* for equality. If bytes are equal function returns 0. |
* |
* @param src Region 1 |
* @param dst Region 2 |
* @param cnt Number of bytes |
* @return Zero if bytes are equal, non-zero otherwise |
*/ |
static inline int memcmp(const void * src, const void * dst, size_t cnt) |
{ |
uint32_t d0, d1, d2; |
int ret; |
asm ( |
"repe cmpsb\n\t" |
"je 1f\n\t" |
"movl %3, %0\n\t" |
"addl $1, %0\n\t" |
"1:\n" |
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2) |
: "0" (0), "1" ((unative_t) src), "2" ((unative_t) dst), "3" ((unative_t) cnt) |
); |
return ret; |
} |
/** Fill memory with words |
* Fill a given number of words (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of words |
* @param x Value to fill |
*/ |
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
{ |
uint32_t d0, d1; |
asm volatile ( |
"rep stosw\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" (cnt), "2" (x) |
: "memory" |
); |
} |
/** Fill memory with bytes |
* Fill a given number of bytes (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of bytes |
* @param x Value to fill |
*/ |
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
{ |
uint32_t d0, d1; |
asm volatile ( |
"rep stosb\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" (cnt), "2" (x) |
: "memory" |
); |
} |
#endif |
/** @} |
/branches/network/kernel/arch/ia32/include/types.h |
---|
35,10 → 35,6 |
#ifndef KERN_ia32_TYPES_H_ |
#define KERN_ia32_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed long int32_t; |
61,14 → 57,29 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
#define PRIp "x" /**< Format for uintptr_t. */ |
#define PRIs "u" /**< Format for size_t. */ |
#define PRIc "u" /**< Format for count_t. */ |
#define PRIi "u" /**< Format for index_t. */ |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
#define PRId32 "d" /**< Format for int32_t. */ |
#define PRId64 "lld" /**< Format for int64_t. */ |
#define PRIdn "d" /**< Format for native_t. */ |
#define PRIu8 "u" /**< Format for uint8_t. */ |
#define PRIu16 "u" /**< Format for uint16_t. */ |
#define PRIu32 "u" /**< Format for uint32_t. */ |
#define PRIu64 "llu" /**< Format for uint64_t. */ |
#define PRIun "u" /**< Format for unative_t. */ |
#define PRIx8 "x" /**< Format for hexadecimal (u)int8_t. */ |
#define PRIx16 "x" /**< Format for hexadecimal (u)int16_t. */ |
#define PRIx32 "x" /**< Format for hexadecimal (u)uint32_t. */ |
#define PRIx64 "llx" /**< Format for hexadecimal (u)int64_t. */ |
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */ |
/** Page Table Entry. */ |
typedef struct { |
unsigned present : 1; |
/branches/network/kernel/arch/ia32/include/smp/apic.h |
---|
105,8 → 105,8 |
#define MODEL_CLUSTER 0x0 |
/** Interrupt Command Register. */ |
#define ICRlo (0x300/sizeof(uint32_t)) |
#define ICRhi (0x310/sizeof(uint32_t)) |
#define ICRlo (0x300 / sizeof(uint32_t)) |
#define ICRhi (0x310 / sizeof(uint32_t)) |
typedef struct { |
union { |
uint32_t lo; |
133,10 → 133,10 |
} __attribute__ ((packed)) icr_t; |
/* End Of Interrupt. */ |
#define EOI (0x0b0/sizeof(uint32_t)) |
#define EOI (0x0b0 / sizeof(uint32_t)) |
/** Error Status Register. */ |
#define ESR (0x280/sizeof(uint32_t)) |
#define ESR (0x280 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
uint8_t err_bitmap; |
154,7 → 154,7 |
} esr_t; |
/* Task Priority Register */ |
#define TPR (0x080/sizeof(uint32_t)) |
#define TPR (0x080 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
164,7 → 164,7 |
} tpr_t; |
/** Spurious-Interrupt Vector Register. */ |
#define SVR (0x0f0/sizeof(uint32_t)) |
#define SVR (0x0f0 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
176,7 → 176,7 |
} svr_t; |
/** Time Divide Configuration Register. */ |
#define TDCR (0x3e0/sizeof(uint32_t)) |
#define TDCR (0x3e0 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
186,13 → 186,13 |
} tdcr_t; |
/* Initial Count Register for Timer */ |
#define ICRT (0x380/sizeof(uint32_t)) |
#define ICRT (0x380 / sizeof(uint32_t)) |
/* Current Count Register for Timer */ |
#define CCRT (0x390/sizeof(uint32_t)) |
#define CCRT (0x390 / sizeof(uint32_t)) |
/** LVT Timer register. */ |
#define LVT_Tm (0x320/sizeof(uint32_t)) |
#define LVT_Tm (0x320 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
207,8 → 207,8 |
} lvt_tm_t; |
/** LVT LINT registers. */ |
#define LVT_LINT0 (0x350/sizeof(uint32_t)) |
#define LVT_LINT1 (0x360/sizeof(uint32_t)) |
#define LVT_LINT0 (0x350 / sizeof(uint32_t)) |
#define LVT_LINT1 (0x360 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
225,7 → 225,7 |
} lvt_lint_t; |
/** LVT Error register. */ |
#define LVT_Err (0x370/sizeof(uint32_t)) |
#define LVT_Err (0x370 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
239,7 → 239,7 |
} lvt_error_t; |
/** Local APIC ID Register. */ |
#define L_APIC_ID (0x020/sizeof(uint32_t)) |
#define L_APIC_ID (0x020 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
249,14 → 249,14 |
} l_apic_id_t; |
/** Local APIC Version Register */ |
#define LAVR (0x030/sizeof(uint32_t)) |
#define LAVR (0x030 / sizeof(uint32_t)) |
#define LAVR_Mask 0xff |
#define is_local_apic(x) (((x)&LAVR_Mask&0xf0)==0x1) |
#define is_82489DX_apic(x) ((((x)&LAVR_Mask&0xf0)==0x0)) |
#define is_local_xapic(x) (((x)&LAVR_Mask)==0x14) |
#define is_local_apic(x) (((x) & LAVR_Mask & 0xf0) == 0x1) |
#define is_82489DX_apic(x) ((((x) & LAVR_Mask & 0xf0) == 0x0)) |
#define is_local_xapic(x) (((x) & LAVR_Mask) == 0x14) |
/** Logical Destination Register. */ |
#define LDR (0x0d0/sizeof(uint32_t)) |
#define LDR (0x0d0 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
266,7 → 266,7 |
} ldr_t; |
/** Destination Format Register. */ |
#define DFR (0x0e0/sizeof(uint32_t)) |
#define DFR (0x0e0 / sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
276,8 → 276,8 |
} dfr_t; |
/* IO APIC */ |
#define IOREGSEL (0x00/sizeof(uint32_t)) |
#define IOWIN (0x10/sizeof(uint32_t)) |
#define IOREGSEL (0x00 / sizeof(uint32_t)) |
#define IOWIN (0x10 / sizeof(uint32_t)) |
#define IOAPICID 0x00 |
#define IOAPICVER 0x01 |
/branches/network/kernel/arch/ia32/include/byteorder.h |
---|
35,15 → 35,9 |
#ifndef KERN_ia32_BYTEORDER_H_ |
#define KERN_ia32_BYTEORDER_H_ |
#include <byteorder.h> |
/* IA-32 is little-endian */ |
#define uint32_t_le2host(n) (n) |
#define uint64_t_le2host(n) (n) |
#define ARCH_IS_LITTLE_ENDIAN |
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n) |
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n) |
#endif |
/** @} |
/branches/network/kernel/arch/ia32/include/context_offset.h |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2008 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32_CONTEXT_OFFSET_H_ |
#define KERN_ia32_CONTEXT_OFFSET_H_ |
#define OFFSET_SP 0x0 |
#define OFFSET_PC 0x4 |
#define OFFSET_EBX 0x8 |
#define OFFSET_ESI 0xC |
#define OFFSET_EDI 0x10 |
#define OFFSET_EBP 0x14 |
#ifdef KERNEL |
# define OFFSET_IPL 0x18 |
#else |
# define OFFSET_TLS 0x18 |
#endif |
#ifdef __ASM__ |
# ctx: address of the structure with saved context |
# pc: return address |
.macro CONTEXT_SAVE_ARCH_CORE ctx:req pc:req |
movl %esp,OFFSET_SP(\ctx) # %esp -> ctx->sp |
movl \pc,OFFSET_PC(\ctx) # %eip -> ctx->pc |
movl %ebx,OFFSET_EBX(\ctx) # %ebx -> ctx->ebx |
movl %esi,OFFSET_ESI(\ctx) # %esi -> ctx->esi |
movl %edi,OFFSET_EDI(\ctx) # %edi -> ctx->edi |
movl %ebp,OFFSET_EBP(\ctx) # %ebp -> ctx->ebp |
.endm |
# ctx: address of the structure with saved context |
.macro CONTEXT_RESTORE_ARCH_CORE ctx:req pc:req |
movl OFFSET_SP(\ctx),%esp # ctx->sp -> %esp |
movl OFFSET_PC(\ctx),\pc # ctx->pc -> \pc |
movl OFFSET_EBX(\ctx),%ebx # ctx->ebx -> %ebx |
movl OFFSET_ESI(\ctx),%esi # ctx->esi -> %esi |
movl OFFSET_EDI(\ctx),%edi # ctx->edi -> %edi |
movl OFFSET_EBP(\ctx),%ebp # ctx->ebp -> %ebp |
.endm |
#endif /* __ASM__ */ |
#endif |
/** @} |
*/ |
/branches/network/kernel/arch/ia32/include/context.h |
---|
35,6 → 35,7 |
#ifndef KERN_ia32_CONTEXT_H_ |
#define KERN_ia32_CONTEXT_H_ |
#ifdef KERNEL |
#include <arch/types.h> |
#define STACK_ITEM_SIZE 4 |
47,6 → 48,8 |
*/ |
#define SP_DELTA (8 + STACK_ITEM_SIZE) |
#endif /* KERNEL */ |
/* |
* Only save registers that must be preserved across |
* function calls. |