/branches/tracing/kernel/arch/sparc64/include/atomic.h |
---|
37,6 → 37,7 |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <preemption.h> |
/** Atomic add operation. |
* |
56,7 → 57,8 |
a = *((uint64_t *) x); |
b = a + i; |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *)x)), "+r" (b) : "r" (a)); |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *)x)), |
"+r" (b) : "r" (a)); |
} while (a != b); |
return a; |
97,7 → 99,8 |
uint64_t v = 1; |
volatile uintptr_t x = (uint64_t) &val->count; |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *) x)), "+r" (v) : "r" (0)); |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *) x)), |
"+r" (v) : "r" (0)); |
return v; |
} |
109,6 → 112,8 |
volatile uintptr_t x = (uint64_t) &val->count; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
"casx %0, %3, %1\n" |
/branches/tracing/kernel/arch/sparc64/include/mm/page.h |
---|
53,11 → 53,6 |
#define MMU_PAGES_PER_PAGE (1 << (PAGE_WIDTH - MMU_PAGE_WIDTH)) |
/* |
* With 16K pages, there is only one page color. |
*/ |
#define PAGE_COLOR_BITS 0 /**< 14 - 14; 2^14 == 16K == alias boundary. */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/tracing/kernel/arch/sparc64/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-sparc |
BFD_ARCH = sparc |
BFD = binary |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/sparc64 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64 |
GCC_CFLAGS += -m64 -mcpu=ultrasparc |
SUNCC_CFLAGS += -m64 -xarch=sparc -xregs=appl,no%float |
/branches/tracing/kernel/arch/sparc64/src/asm.S |
---|
41,6 → 41,7 |
*/ |
.global memcpy |
memcpy: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
59,7 → 60,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
93,7 → 94,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
/* |
* Almost the same as memcpy() except the loads are from userspace. |
100,6 → 101,7 |
*/ |
.global memcpy_from_uspace |
memcpy_from_uspace: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
118,7 → 120,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
152,7 → 154,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
/* |
* Almost the same as memcpy() except the stores are to userspace. |
159,6 → 161,7 |
*/ |
.global memcpy_to_uspace |
memcpy_to_uspace: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
177,7 → 180,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
211,7 → 214,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o1, %o0 |
mov %o3, %o0 |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
274,6 → 277,8 |
wrpr %g0, 0, %cleanwin ! avoid information leak |
mov %i2, %o0 ! uarg |
xor %o1, %o1, %o1 ! %o1 is defined to hold pcb_ptr |
! set it to 0 |
clr %i2 |
clr %i3 |
/branches/tracing/kernel/arch/ia64/include/mm/page.h |
---|
41,8 → 41,6 |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
/** Bit width of the TLB-locked portion of kernel address space. */ |
/branches/tracing/kernel/arch/ia64/Makefile.inc |
---|
29,14 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-little |
BFD_ARCH = ia64-elf64 |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ia64 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64 |
INIT0_ADDRESS = 0xe000000004404000 |
INIT0_SIZE = 0x100000 |
CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127 |
GCC_CFLAGS += $(CMN1) |
ICC_CFLAGS += $(CMN1) |
44,9 → 45,8 |
LFLAGS += -EL |
AFLAGS += -mconstant-gp |
DEFS += -D__64_BITS__ -DINIT0_ADDRESS=$(INIT0_ADDRESS) -DINIT0_SIZE=$(INIT0_SIZE) -D$(MACHINE) |
DEFS += -D__64_BITS__ -D$(MACHINE) |
## Compile with page hash table support. |
# |
96,6 → 96,5 |
CONFIG_I8042 = y |
DEFS += -DI460GX -DCONFIG_I8042 |
BFD = binary |
endif |
/branches/tracing/kernel/arch/ia64/src/asm.S |
---|
51,7 → 51,7 |
adds r14 = 7, in1 |
mov r2 = ar.lc |
mov r8 = in1 ;; |
mov r8 = in0 |
and r14 = -8, r14 ;; |
cmp.ne p6, p7 = r14, in1 |
(p7) br.cond.dpnt 3f ;; |
63,7 → 63,7 |
(p6) mov r17 = r0 ;; |
(p6) mov ar.lc = r14 |
1: |
add r14 = r16, r8 |
add r14 = r16, in1 |
add r15 = r16, in0 |
adds r17 = 1, r17 ;; |
ld1 r14 = [r14] |
72,7 → 72,6 |
br.cloop.sptk.few 1b ;; |
2: |
mov ar.lc = r2 |
mov ar.pfs = loc0 |
br.ret.sptk.many rp |
3: |
90,7 → 89,7 |
4: |
shladd r14 = r16, 3, r0 |
adds r16 = 1, r17 ;; |
add r15 = r8, r14 |
add r15 = in1, r14 |
add r14 = in0, r14 |
mov r17 = r16 ;; |
ld8 r15 = [r15] ;; |
104,7 → 103,7 |
cmp.eq p6, p7 = 0, r15 |
add in0 = r14, in0 |
adds r15 = -1, r15 |
add r17 = r14, r8 |
add r17 = r14, in1 |
(p6) br.cond.dpnt 2b ;; |
mov ar.lc = r15 |
6: |
116,7 → 115,6 |
st1 [r15] = r14 |
br.cloop.sptk.few 6b ;; |
mov ar.lc = r2 |
mov ar.pfs = loc0 |
br.ret.sptk.many rp |
163,6 → 161,9 |
xor r1 = r1, r1 |
/* r2 is defined to hold pcb_ptr - set it to 0 */ |
xor r2 = r2, r2 |
mov loc1 = cr.ifs |
movl loc2 = PFM_MASK ;; |
and loc1 = loc2, loc1 ;; |
/branches/tracing/kernel/arch/arm32/include/mm/page.h |
---|
43,8 → 43,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
/branches/tracing/kernel/arch/arm32/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-littlearm |
BFD_ARCH = arm |
BFD = binary |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = /usr/local/arm |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm |
KERNEL_LOAD_ADDRESS = 0x80200000 |
/branches/tracing/kernel/arch/arm32/src/asm.S |
---|
45,7 → 45,8 |
add r3, r1, #3 |
bic r3, r3, #3 |
cmp r1, r3 |
stmdb sp!, {r4, lr} |
stmdb sp!, {r4, r5, lr} |
mov r5, r0 /* save dst */ |
beq 4f |
1: |
cmp r2, #0 |
58,8 → 59,8 |
cmp ip, r2 |
bne 2b |
3: |
mov r0, r1 |
ldmia sp!, {r4, pc} |
mov r0, r5 |
ldmia sp!, {r4, r5, pc} |
4: |
add r3, r0, #3 |
bic r3, r3, #3 |
94,5 → 95,5 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
mov r0, #0 |
ldmia sp!, {r4, pc} |
mov r0, #0 |
ldmia sp!, {r4, r5, pc} |
/branches/tracing/kernel/arch/arm32/src/userspace.c |
---|
70,8 → 70,11 |
/* set first parameter */ |
ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg; |
/* %r1 is defined to hold pcb_ptr - set it to 0 */ |
ustate.r1 = 0; |
/* clear other registers */ |
ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 = |
ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 = |
ustate.r6 = ustate.r7 = ustate.r8 = ustate.r9 = ustate.r10 = |
ustate.r11 = ustate.r12 = ustate.lr = 0; |
/branches/tracing/kernel/arch/ppc32/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__ |
/branches/tracing/kernel/arch/ppc32/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-powerpc |
BFD_ARCH = powerpc:common |
BFD = binary |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc |
GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32 |
AFLAGS += -a32 |
/branches/tracing/kernel/arch/ppc32/src/asm.S |
---|
65,6 → 65,10 |
# set stack |
mr sp, r4 |
# %r3 is defined to hold pcb_ptr - set it to 0 |
xor r3, r3, r3 |
# jump to userspace |
199,47 → 203,7 |
rfi |
memsetb: |
rlwimi r5, r5, 8, 16, 23 |
rlwimi r5, r5, 16, 0, 15 |
addi r14, r3, -4 |
cmplwi 0, r4, 4 |
blt 7f |
stwu r5, 4(r14) |
beqlr |
andi. r15, r14, 3 |
add r4, r15, r4 |
subf r14, r15, r14 |
srwi r15, r4, 2 |
mtctr r15 |
bdz 6f |
1: |
stwu r5, 4(r14) |
bdnz 1b |
6: |
andi. r4, r4, 3 |
7: |
cmpwi 0, r4, 0 |
beqlr |
mtctr r4 |
addi r6, r6, 3 |
8: |
stbu r5, 1(r14) |
bdnz 8b |
blr |
b _memsetb |
memcpy: |
memcpy_from_uspace: |
308,4 → 272,6 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
b memcpy_from_uspace_failover_address |
# return zero, failure |
xor r3, r3, r3 |
blr |
/branches/tracing/kernel/arch/ppc32/src/mm/tlb.c |
---|
47,16 → 47,19 |
* The as->lock must be held on entry to this function |
* if lock is true. |
* |
* @param as Address space. |
* @param lock Lock/unlock the address space. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @return PTE on success, NULL otherwise. |
* @param as Address space. |
* @param lock Lock/unlock the address space. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code |
* will be stored. |
* @return PTE on success, NULL otherwise. |
* |
*/ |
static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, istate_t *istate, int *pfrc) |
static pte_t * |
find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, |
istate_t *istate, int *pfrc) |
{ |
/* |
* Check if the mapping exists in page tables. |
77,27 → 80,27 |
*/ |
page_table_unlock(as, lock); |
switch (rc = as_page_fault(badvaddr, access, istate)) { |
case AS_PF_OK: |
/* |
* The higher-level page fault handler succeeded, |
* The mapping ought to be in place. |
*/ |
page_table_lock(as, lock); |
pte = page_mapping_find(as, badvaddr); |
ASSERT((pte) && (pte->p)); |
*pfrc = 0; |
return pte; |
case AS_PF_DEFER: |
page_table_lock(as, lock); |
*pfrc = rc; |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfrc = rc; |
return NULL; |
default: |
panic("unexpected rc (%d)\n", rc); |
case AS_PF_OK: |
/* |
* The higher-level page fault handler succeeded, |
* The mapping ought to be in place. |
*/ |
page_table_lock(as, lock); |
pte = page_mapping_find(as, badvaddr); |
ASSERT((pte) && (pte->p)); |
*pfrc = 0; |
return pte; |
case AS_PF_DEFER: |
page_table_lock(as, lock); |
*pfrc = rc; |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfrc = rc; |
return NULL; |
default: |
panic("unexpected rc (%d)\n", rc); |
} |
} |
} |
114,7 → 117,8 |
s = get_symtab_entry(istate->lr); |
if (s) |
sym2 = s; |
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); |
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, |
istate->pc, symbol, sym2); |
} |
147,7 → 151,8 |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) { |
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && |
(phte[base + i].api == api))) { |
found = true; |
break; |
} |
160,7 → 165,9 |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) { |
if ((!phte[base2 + i].v) || |
((phte[base2 + i].vsid == vsid) && |
(phte[base2 + i].api == api))) { |
found = true; |
base = base2; |
h = 1; |
214,7 → 221,9 |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte_physical[base + i].v) || ((phte_physical[base + i].vsid == vsid) && (phte_physical[base + i].api == api))) { |
if ((!phte_physical[base + i].v) || |
((phte_physical[base + i].vsid == vsid) && |
(phte_physical[base + i].api == api))) { |
found = true; |
break; |
} |
227,7 → 236,9 |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) { |
if ((!phte_physical[base2 + i].v) || |
((phte_physical[base2 + i].vsid == vsid) && |
(phte_physical[base2 + i].api == api))) { |
found = true; |
base = base2; |
h = 1; |
254,8 → 265,8 |
/** Process Instruction/Data Storage Interrupt |
* |
* @param n Interrupt vector number. |
* @param istate Interrupted register context. |
* @param n Interrupt vector number. |
* @param istate Interrupted register context. |
* |
*/ |
void pht_refill(int n, istate_t *istate) |
284,21 → 295,22 |
page_table_lock(as, lock); |
pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
pte = find_mapping_and_check(as, lock, badvaddr, |
PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(as, lock); |
return; |
default: |
panic("Unexpected pfrc (%d)\n", pfrc); |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(as, lock); |
return; |
default: |
panic("Unexpected pfrc (%d)\n", pfrc); |
} |
} |
316,8 → 328,8 |
/** Process Instruction/Data Storage Interrupt in Real Mode |
* |
* @param n Interrupt vector number. |
* @param istate Interrupted register context. |
* @param n Interrupt vector number. |
* @param istate Interrupted register context. |
* |
*/ |
bool pht_real_refill(int n, istate_t *istate) |
373,7 → 385,8 |
uint32_t i; |
for (i = 0; i < 8192; i++) { |
if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && (phte[i].vsid < ((asid << 4) + 16))) |
if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && |
(phte[i].vsid < ((asid << 4) + 16))) |
phte[i].v = 0; |
} |
tlb_invalidate_all(); |
407,7 → 420,11 |
} \ |
} else \ |
length = 0; \ |
printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, lower & 0xffff0000, length, mask, ((upper >> 1) & 1) ? " supervisor" : "", (upper & 1) ? " user" : ""); |
printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \ |
sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \ |
lower & 0xffff0000, length, mask, \ |
((upper >> 1) & 1) ? " supervisor" : "", \ |
(upper & 1) ? " user" : ""); |
void tlb_print(void) |
421,7 → 438,10 |
: "=r" (vsid) |
: "r" (sr << 28) |
); |
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, ((vsid >> 30) & 1) ? " supervisor" : "", ((vsid >> 29) & 1) ? " user" : ""); |
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, |
sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, |
((vsid >> 30) & 1) ? " supervisor" : "", |
((vsid >> 29) & 1) ? " user" : ""); |
} |
uint32_t upper; |
/branches/tracing/kernel/arch/ppc32/src/mm/page.c |
---|
47,13 → 47,16 |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%" PRIs " bytes)", physaddr, size) |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > |
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%" PRIs " bytes)", |
physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) |
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), |
physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
/branches/tracing/kernel/arch/ia32xen/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__ |
/branches/tracing/kernel/arch/ia32xen/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = elf32-i386 |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
/branches/tracing/kernel/arch/ia32xen/src/asm.S |
---|
67,7 → 67,7 |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_SRC(%esp) on success and 0 on failure. |
* @return MEMCPY_DST(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
92,7 → 92,7 |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */ |
movl MEMCPY_DST(%esp), %eax /* MEMCPY_DST(%esp), success */ |
ret |
/* |
/branches/tracing/kernel/arch/ia32xen/src/userspace.c |
---|
68,6 → 68,10 |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
/* %ebx is defined to hold pcb_ptr - set it to 0 */ |
"xorl %%ebx, %%ebx\n" |
"iret\n" |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
/branches/tracing/kernel/arch/amd64/include/atomic.h |
---|
108,13 → 108,13 |
#endif |
"mov %0, %1\n" |
"testq %1, %1\n" |
"jnz 0b\n" /* Lightweight looping on locked spinlock */ |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"incq %1\n" /* now use the atomic operation */ |
"xchgq %0, %1\n" |
"testq %1, %1\n" |
"jnz 0b\n" |
: "+m" (val->count), "=r"(tmp) |
: "+m" (val->count), "=&r" (tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/tracing/kernel/arch/amd64/include/mm/page.h |
---|
52,8 → 52,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/tracing/kernel/arch/amd64/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-x86-64 |
BFD_ARCH = i386:x86-64 |
BFD = binary |
TARGET = amd64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/amd64 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64 |
FPU_NO_CFLAGS = -mno-sse -mno-sse2 |
CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables |
/branches/tracing/kernel/arch/amd64/src/asm_utils.S |
---|
98,12 → 98,12 |
* @param MEMCPY_SRC Source address. |
* @param MEMCPY_SIZE Number of bytes to copy. |
* |
* @retrun MEMCPY_SRC on success, 0 on failure. |
* @retrun MEMCPY_DST on success, 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
movq MEMCPY_SRC, %rax |
movq MEMCPY_DST, %rax |
movq MEMCPY_SIZE, %rcx |
shrq $3, %rcx /* size / 8 */ |
/branches/tracing/kernel/arch/amd64/src/userspace.c |
---|
61,6 → 61,8 |
"pushq %3\n" |
"pushq %4\n" |
"movq %5, %%rax\n" |
/* %rdi is defined to hold pcb_ptr - set it to 0 */ |
"xorq %%rdi, %%rdi\n" |
"iretq\n" |
: : |
"i" (gdtselector(UDATA_DES) | PL_USER), |
/branches/tracing/kernel/arch/ppc64/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__ |
/branches/tracing/kernel/arch/ppc64/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-powerpc |
BFD_ARCH = powerpc:common64 |
BFD = binary |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc64 |
GCC_CFLAGS += -mcpu=powerpc64 -msoft-float -m64 |
AFLAGS += -a64 |
/branches/tracing/kernel/arch/ppc64/src/asm.S |
---|
66,6 → 66,10 |
mr sp, r4 |
# %r3 is defined to hold pcb_ptr - set it to 0 |
xor r3, r3, r3 |
# jump to userspace |
rfi |
/branches/tracing/kernel/arch/mips32/include/mm/page.h |
---|
40,8 → 40,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
/branches/tracing/kernel/arch/mips32/include/mm/tlb.h |
---|
35,6 → 35,9 |
#ifndef KERN_mips32_TLB_H_ |
#define KERN_mips32_TLB_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/mm/asid.h> |
#include <arch/exception.h> |
#ifdef TLBCNT |
46,7 → 49,13 |
#define TLB_WIRED 1 |
#define TLB_KSTACK_WIRED_INDEX 0 |
#define TLB_PAGE_MASK_16K (0x3<<13) |
#define TLB_PAGE_MASK_4K (0x000 << 13) |
#define TLB_PAGE_MASK_16K (0x003 << 13) |
#define TLB_PAGE_MASK_64K (0x00f << 13) |
#define TLB_PAGE_MASK_256K (0x03f << 13) |
#define TLB_PAGE_MASK_1M (0x0ff << 13) |
#define TLB_PAGE_MASK_4M (0x3ff << 13) |
#define TLB_PAGE_MASK_16M (0xfff << 13) |
#define PAGE_UNCACHED 2 |
#define PAGE_CACHEABLE_EXC_WRITE 5 |
159,6 → 168,8 |
extern void tlb_invalid(istate_t *istate); |
extern void tlb_refill(istate_t *istate); |
extern void tlb_modified(istate_t *istate); |
extern void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
extern void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
#endif |
/branches/tracing/kernel/arch/mips32/include/mm/as.h |
---|
38,7 → 38,7 |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x80000000 |
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffff |
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0x9fffffff |
#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x00000000 |
#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x7fffffff |
/branches/tracing/kernel/arch/mips32/include/drivers/arc.h |
---|
File deleted |
/branches/tracing/kernel/arch/mips32/include/drivers/serial.h |
---|
37,6 → 37,8 |
#include <console/chardev.h> |
#define SERIAL_ADDRESS 0x98000000 |
#define SERIAL_MAX 4 |
#define SERIAL_COM1 0x3f8 |
#define SERIAL_COM1_IRQ 4 |
43,16 → 45,19 |
#define SERIAL_COM2 0x2f8 |
#define SERIAL_COM2_IRQ 3 |
#define P_WRITEB(where,what) (*((volatile char *) (0xB8000000+where))=what) |
#define P_READB(where) (*((volatile char *)(0xB8000000+where))) |
#define P_WRITEB(where, what) (*((volatile char *) (SERIAL_ADDRESS + where)) = what) |
#define P_READB(where) (*((volatile char *) (SERIAL_ADDRESS + where))) |
#define SERIAL_READ(x) P_READB(x) |
#define SERIAL_WRITE(x,c) P_WRITEB(x,c) |
#define SERIAL_READ(x) P_READB(x) |
#define SERIAL_WRITE(x, c) P_WRITEB(x, c) |
/* Interrupt enable register */ |
#define SERIAL_READ_IER(x) (P_READB((x) + 1)) |
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x)+1,c)) |
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x) + 1, c)) |
/* Interrupt identification register */ |
#define SERIAL_READ_IIR(x) (P_READB((x) + 2)) |
/* Line status register */ |
#define SERIAL_READ_LSR(x) (P_READB((x) + 5)) |
#define TRANSMIT_EMPTY_BIT 5 |
/branches/tracing/kernel/arch/mips32/include/drivers/msim.h |
---|
35,6 → 35,11 |
#ifndef KERN_mips32_MSIM_H_ |
#define KERN_mips32_MSIM_H_ |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0x90000000 |
#define MSIM_KBD_ADDRESS 0x90000000 |
#define MSIM_KBD_IRQ 2 |
#include <console/chardev.h> |
void msim_console(devno_t devno); |
/branches/tracing/kernel/arch/mips32/Makefile.inc |
---|
29,17 → 29,19 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_ARCH = mips |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = /usr/local/mipsel |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel |
KERNEL_LOAD_ADDRESS = 0x80100000 |
INIT_ADDRESS = 0x81000000 |
INIT_SIZE = 262144 |
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} -DINIT_ADDRESS=${INIT_ADDRESS} -DINIT_SIZE=${INIT_SIZE} |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} |
## Compile with hierarchical page tables support. |
# |
56,20 → 58,6 |
## Accepted MACHINEs |
# |
ifeq ($(MACHINE),indy) |
# GCC 4.0.1 compiled for mipsEL has problems compiling in |
# BigEndian mode with the swl/swr/lwl/lwr instructions. |
# We have to compile it with mips-sgi-irix5 to get it right. |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips --impure |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
KERNEL_LOAD_ADDRESS = 0x88002000 |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -march=r4600 |
INIT_ADDRESS = 0 |
INIT_SIZE = 0 |
endif |
ifeq ($(MACHINE),lgxemul) |
BFD_NAME = elf32-tradlittlemips |
BFD = binary |
79,9 → 67,8 |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3 |
INIT_ADDRESS = 0x81800000 |
endif |
ifeq ($(MACHINE),simics) |
# SIMICS 4kc emulation is broken, although for instructions |
123,7 → 110,6 |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/arc.c \ |
arch/$(ARCH)/src/drivers/msim.c \ |
arch/$(ARCH)/src/drivers/serial.c \ |
arch/$(ARCH)/src/smp/order.c |
/branches/tracing/kernel/arch/mips32/src/asm.S |
---|
71,6 → 71,7 |
and $v0,$v0,$v1 |
beq $a1,$v0,3f |
move $t0,$a0 |
move $t2,$a0 # save dst |
0: |
beq $a2,$zero,2f |
86,7 → 87,7 |
2: |
jr $ra |
move $v0,$a1 |
move $v0,$t2 |
3: |
addiu $v0,$a0,3 |
126,7 → 127,7 |
sb $a0,0($v1) |
jr $ra |
move $v0,$a1 |
move $v0,$t2 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
/branches/tracing/kernel/arch/mips32/src/console.c |
---|
34,18 → 34,15 |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/drivers/arc.h> |
#include <arch/drivers/serial.h> |
#include <arch/drivers/msim.h> |
void console_init(devno_t devno) |
{ |
if (!arc_console()) { |
if (serial_init()) |
serial_console(devno); |
else |
msim_console(devno); |
} |
if (serial_init()) |
serial_console(devno); |
else |
msim_console(devno); |
} |
/** Acquire console back for kernel |
/branches/tracing/kernel/arch/mips32/src/mips32.c |
---|
48,7 → 48,6 |
#include <sysinfo/sysinfo.h> |
#include <arch/interrupt.h> |
#include <arch/drivers/arc.h> |
#include <console/chardev.h> |
#include <arch/barrier.h> |
#include <arch/debugger.h> |
97,7 → 96,6 |
/* Initialize dispatch table */ |
exception_init(); |
arc_init(); |
/* Copy the exception vectors to the right places */ |
memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE); |
187,8 → 185,7 |
void arch_reboot(void) |
{ |
if (!arc_reboot()) |
___halt(); |
___halt(); |
while (1) |
; |
/branches/tracing/kernel/arch/mips32/src/start.S |
---|
349,5 → 349,7 |
userspace_asm: |
add $sp, $a0, 0 |
add $v0, $a1, 0 |
add $t9, $a2, 0 # Set up correct entry into PIC code |
add $t9, $a2, 0 # Set up correct entry into PIC code |
xor $a0, $a0, $a0 # $a0 is defined to hold pcb_ptr |
# set it to 0 |
eret |
/branches/tracing/kernel/arch/mips32/src/mm/tlb.c |
---|
47,18 → 47,14 |
#include <align.h> |
#include <interrupt.h> |
static void tlb_refill_fail(istate_t *istate); |
static void tlb_invalid_fail(istate_t *istate); |
static void tlb_modified_fail(istate_t *istate); |
static void tlb_refill_fail(istate_t *); |
static void tlb_invalid_fail(istate_t *); |
static void tlb_modified_fail(istate_t *); |
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc); |
static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *, int *); |
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
/** Initialize TLB |
/** Initialize TLB. |
* |
* Initialize TLB. |
* Invalidate all entries and mark wired entries. |
*/ |
void tlb_arch_init(void) |
76,7 → 72,6 |
cp0_index_write(i); |
tlbwi(); |
} |
/* |
* The kernel is going to make use of some wired |
85,11 → 80,9 |
cp0_wired_write(TLB_WIRED); |
} |
/** Process TLB Refill Exception |
/** Process TLB Refill Exception. |
* |
* Process TLB Refill Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_refill(istate_t *istate) |
{ |
131,14 → 124,15 |
*/ |
pte->a = 1; |
prepare_entry_hi(&hi, asid, badvaddr); |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
tlb_prepare_entry_hi(&hi, asid, badvaddr); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
/* |
* New entry is to be inserted into TLB |
*/ |
cp0_entry_hi_write(hi.value); |
if ((badvaddr/PAGE_SIZE) % 2 == 0) { |
if ((badvaddr / PAGE_SIZE) % 2 == 0) { |
cp0_entry_lo0_write(lo.value); |
cp0_entry_lo1_write(0); |
} |
157,11 → 151,9 |
tlb_refill_fail(istate); |
} |
/** Process TLB Invalid Exception |
/** Process TLB Invalid Exception. |
* |
* Process TLB Invalid Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_invalid(istate_t *istate) |
{ |
178,7 → 170,7 |
* Locate the faulting entry in TLB. |
*/ |
hi.value = cp0_entry_hi_read(); |
prepare_entry_hi(&hi, hi.asid, badvaddr); |
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
index.value = cp0_index_read(); |
221,12 → 213,13 |
*/ |
pte->a = 1; |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
/* |
* The entry is to be updated in TLB. |
*/ |
if ((badvaddr/PAGE_SIZE) % 2 == 0) |
if ((badvaddr / PAGE_SIZE) % 2 == 0) |
cp0_entry_lo0_write(lo.value); |
else |
cp0_entry_lo1_write(lo.value); |
241,11 → 234,9 |
tlb_invalid_fail(istate); |
} |
/** Process TLB Modified Exception |
/** Process TLB Modified Exception. |
* |
* Process TLB Modified Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_modified(istate_t *istate) |
{ |
262,7 → 253,7 |
* Locate the faulting entry in TLB. |
*/ |
hi.value = cp0_entry_hi_read(); |
prepare_entry_hi(&hi, hi.asid, badvaddr); |
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
index.value = cp0_index_read(); |
296,12 → 287,6 |
} |
/* |
* Fail if the page is not writable. |
*/ |
if (!pte->w) |
goto fail; |
/* |
* Read the faulting TLB entry. |
*/ |
tlbr(); |
312,12 → 297,13 |
pte->a = 1; |
pte->d = 1; |
prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, |
pte->pfn); |
/* |
* The entry is to be updated in TLB. |
*/ |
if ((badvaddr/PAGE_SIZE) % 2 == 0) |
if ((badvaddr / PAGE_SIZE) % 2 == 0) |
cp0_entry_lo0_write(lo.value); |
else |
cp0_entry_lo1_write(lo.value); |
344,8 → 330,10 |
if (s) |
sym2 = s; |
fault_if_from_uspace(istate, "TLB Refill Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2); |
fault_if_from_uspace(istate, "TLB Refill Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol, sym2); |
} |
356,8 → 344,10 |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
void tlb_modified_fail(istate_t *istate) |
367,23 → 357,27 |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Modified Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
fault_if_from_uspace(istate, "TLB Modified Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
/** Try to find PTE for faulting address |
/** Try to find PTE for faulting address. |
* |
* Try to find PTE for faulting address. |
* The AS->lock must be held on entry to this function. |
* |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code |
* will be stored. |
* |
* @return PTE on success, NULL otherwise. |
* @return PTE on success, NULL otherwise. |
*/ |
pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc) |
pte_t * |
find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, |
int *pfrc) |
{ |
entry_hi_t hi; |
pte_t *pte; |
402,7 → 396,7 |
* Check if the mapping exists in page tables. |
*/ |
pte = page_mapping_find(AS, badvaddr); |
if (pte && pte->p) { |
if (pte && pte->p && (pte->w || access != PF_ACCESS_WRITE)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
425,6 → 419,7 |
page_table_lock(AS, true); |
pte = page_mapping_find(AS, badvaddr); |
ASSERT(pte && pte->p); |
ASSERT(pte->w || access != PF_ACCESS_WRITE); |
return pte; |
break; |
case AS_PF_DEFER: |
445,7 → 440,9 |
} |
} |
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn) |
void |
tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, |
uintptr_t pfn) |
{ |
lo->value = 0; |
lo->g = g; |
455,7 → 452,7 |
lo->pfn = pfn; |
} |
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
{ |
hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2); |
hi->asid = asid; |
484,10 → 481,10 |
lo1.value = cp0_entry_lo1_read(); |
printf("%-2u %-4u %#6x %#4x %1u %1u %1u %1u %#6x\n", |
i, hi.asid, hi.vpn2, mask.mask, |
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn); |
i, hi.asid, hi.vpn2, mask.mask, |
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn); |
printf(" %1u %1u %1u %1u %#6x\n", |
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn); |
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn); |
} |
cp0_entry_hi_write(hi_save.value); |
564,11 → 561,12 |
cp0_entry_hi_write(hi_save.value); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
/** Invalidate TLB entries for specified page range belonging to specified |
* address space. |
* |
* @param asid Address space identifier. |
* @param page First page whose TLB entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
* @param asid Address space identifier. |
* @param page First page whose TLB entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
585,7 → 583,7 |
for (i = 0; i < cnt + 1; i += 2) { |
hi.value = 0; |
prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
tlb_prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
592,7 → 590,10 |
index.value = cp0_index_read(); |
if (!index.p) { |
/* Entry was found, index register contains valid index. */ |
/* |
* Entry was found, index register contains valid |
* index. |
*/ |
tlbr(); |
lo0.value = cp0_entry_lo0_read(); |
/branches/tracing/kernel/arch/mips32/src/mm/as.c |
---|
44,7 → 44,7 |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
as_operations = &as_pt_operations; |
asid_fifo_init(); |
} |
/branches/tracing/kernel/arch/mips32/src/mm/frame.c |
---|
32,27 → 32,238 |
/** @file |
*/ |
#include <macros.h> |
#include <arch/mm/frame.h> |
#include <arch/mm/tlb.h> |
#include <interrupt.h> |
#include <mm/frame.h> |
#include <mm/asid.h> |
#include <config.h> |
#include <arch/drivers/arc.h> |
#include <arch/drivers/msim.h> |
#include <arch/drivers/serial.h> |
#include <print.h> |
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K |
#define ZERO_FRAMES 2048 |
#define ZERO_PAGE_WIDTH 18 /* 256K */ |
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH) |
#define ZERO_PAGE_ASID ASID_INVALID |
#define ZERO_PAGE_TLBI 0 |
#define ZERO_PAGE_ADDR 0 |
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1) |
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET]) |
#define ZERO_PAGE_VALUE_KSEG1(frame) (((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET]) |
#define MAX_REGIONS 32 |
typedef struct { |
pfn_t start; |
pfn_t count; |
} phys_region_t; |
static count_t phys_regions_count = 0; |
static phys_region_t phys_regions[MAX_REGIONS]; |
/** Check whether frame is available |
* |
* Returns true if given frame is generally available for use. |
* Returns false if given frame is used for physical memory |
* mapped devices and cannot be used. |
* |
*/ |
static bool frame_available(pfn_t frame) |
{ |
#if MACHINE == msim |
/* MSIM device (dprinter) */ |
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH)) |
return false; |
/* MSIM device (dkeyboard) */ |
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if MACHINE == simics |
/* Simics device (serial line) */ |
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if (MACHINE == lgxemul) || (MACHINE == bgxemul) |
/* gxemul devices */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
0x10000000, MB2SIZE(256))) |
return false; |
#endif |
return true; |
} |
/** Check whether frame is safe to write |
* |
* Returns true if given frame is safe for read/write test. |
* Returns false if given frame should not be touched. |
* |
*/ |
static bool frame_safe(pfn_t frame) |
{ |
/* Kernel structures */ |
if ((frame << ZERO_PAGE_WIDTH) < KA2PA(config.base)) |
return false; |
/* Kernel */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(config.base), config.kernel_size)) |
return false; |
/* Kernel stack */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(config.stack_base), config.stack_size)) |
return false; |
/* Init tasks */ |
bool safe = true; |
count_t i; |
for (i = 0; i < init.cnt; i++) |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(init.tasks[i].addr), init.tasks[i].size)) { |
safe = false; |
break; |
} |
return safe; |
} |
static void frame_add_region(pfn_t start_frame, pfn_t end_frame) |
{ |
if (end_frame > start_frame) { |
/* Convert 1M frames to 16K frames */ |
pfn_t first = ADDR2PFN(start_frame << ZERO_PAGE_WIDTH); |
pfn_t count = ADDR2PFN((end_frame - start_frame) << ZERO_PAGE_WIDTH); |
/* Interrupt vector frame is blacklisted */ |
pfn_t conf_frame; |
if (first == 0) |
conf_frame = 1; |
else |
conf_frame = first; |
zone_create(first, count, conf_frame, 0); |
if (phys_regions_count < MAX_REGIONS) { |
phys_regions[phys_regions_count].start = first; |
phys_regions[phys_regions_count].count = count; |
phys_regions_count++; |
} |
} |
} |
/** Create memory zones |
* |
* If ARC is known, read information from ARC, otherwise |
* assume some defaults. |
* - blacklist first FRAME because there is an exception vector |
* Walk through available 256 KB chunks of physical |
* memory and create zones. |
* |
* Note: It is assumed that the TLB is not yet being |
* used in any way, thus there is no interference. |
* |
*/ |
void frame_arch_init(void) |
{ |
if (!arc_frame_init()) { |
zone_create(0, ADDR2PFN(CONFIG_MEMORY_SIZE), 1, 0); |
/* |
* Blacklist interrupt vector |
*/ |
frame_mark_unavailable(0, 1); |
ipl_t ipl = interrupts_disable(); |
/* Clear and initialize TLB */ |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(0); |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
count_t i; |
for (i = 0; i < TLB_ENTRY_COUNT; i++) { |
cp0_index_write(i); |
tlbwi(); |
} |
pfn_t start_frame = 0; |
pfn_t frame; |
bool avail = true; |
/* Walk through all 1 MB frames */ |
for (frame = 0; frame < ZERO_FRAMES; frame++) { |
if (!frame_available(frame)) |
avail = false; |
else { |
if (frame_safe(frame)) { |
entry_lo_t lo0; |
entry_lo_t lo1; |
entry_hi_t hi; |
tlb_prepare_entry_lo(&lo0, false, true, true, false, frame << (ZERO_PAGE_WIDTH - 12)); |
tlb_prepare_entry_lo(&lo1, false, false, false, false, 0); |
tlb_prepare_entry_hi(&hi, ZERO_PAGE_ASID, ZERO_PAGE_ADDR); |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(lo0.value); |
cp0_entry_lo1_write(lo1.value); |
cp0_entry_hi_write(hi.value); |
cp0_index_write(ZERO_PAGE_TLBI); |
tlbwi(); |
ZERO_PAGE_VALUE = 0; |
if (ZERO_PAGE_VALUE != 0) |
avail = false; |
else { |
ZERO_PAGE_VALUE = 0xdeadbeef; |
if (ZERO_PAGE_VALUE != 0xdeadbeef) |
avail = false; |
#if (MACHINE == lgxemul) || (MACHINE == bgxemul) |
else { |
ZERO_PAGE_VALUE_KSEG1(frame) = 0xaabbccdd; |
if (ZERO_PAGE_VALUE_KSEG1(frame) != 0xaabbccdd) |
avail = false; |
} |
#endif |
} |
} |
} |
if (!avail) { |
frame_add_region(start_frame, frame); |
start_frame = frame + 1; |
avail = true; |
} |
} |
frame_add_region(start_frame, frame); |
/* Blacklist interrupt vector frame */ |
frame_mark_unavailable(0, 1); |
/* Cleanup */ |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(0); |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
cp0_index_write(ZERO_PAGE_TLBI); |
tlbwi(); |
interrupts_restore(ipl); |
} |
void physmem_print(void) |
{ |
printf("Base Size\n"); |
printf("---------- ----------\n"); |
count_t i; |
for (i = 0; i < phys_regions_count; i++) { |
printf("%#010x %10u\n", |
PFN2ADDR(phys_regions[i].start), PFN2ADDR(phys_regions[i].count)); |
} |
} |
/** @} |
*/ |
/branches/tracing/kernel/arch/mips32/src/interrupt.c |
---|
38,7 → 38,6 |
#include <arch.h> |
#include <arch/cp0.h> |
#include <time/clock.h> |
#include <arch/drivers/arc.h> |
#include <ipc/sysipc.h> |
#include <ddi/device.h> |
/branches/tracing/kernel/arch/mips32/src/drivers/arc.c |
---|
File deleted |
/branches/tracing/kernel/arch/mips32/src/drivers/msim.c |
---|
39,12 → 39,9 |
#include <arch/cp0.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0xB0000000 |
#define MSIM_KBD_ADDRESS 0xB0000000 |
#define MSIM_KBD_IRQ 2 |
static parea_t msim_parea; |
static chardev_t console; |
static irq_t msim_irq; |
158,6 → 155,16 |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS); |
msim_parea.pbase = KA2PA(MSIM_VIDEORAM); |
msim_parea.vbase = MSIM_VIDEORAM; |
msim_parea.frames = 1; |
msim_parea.cacheable = false; |
ddi_parea_register(&msim_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 3); |
sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(MSIM_VIDEORAM)); |
} |
/** @} |
/branches/tracing/kernel/arch/ia32/include/atomic.h |
---|
113,7 → 113,7 |
"xchgl %0, %1\n" |
"testl %1, %1\n" |
"jnz 0b\n" |
: "+m" (val->count), "=r"(tmp) |
: "+m" (val->count), "=&r"(tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/tracing/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__ |
/branches/tracing/kernel/arch/ia32/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = binary |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
74,7 → 78,7 |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),core) |
FPU_NO_CFLAGS = -mno-mmmx -mno-sse -mno-sse2 -mno-sse3 |
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3 |
CMN2 = -march=prescott |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
/branches/tracing/kernel/arch/ia32/src/asm.S |
---|
71,7 → 71,7 |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_SRC(%esp) on success and 0 on failure. |
* @return MEMCPY_DST(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
96,7 → 96,7 |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */ |
movl MEMCPY_DST(%esp), %eax /* MEMCPY_DST(%esp), success */ |
ret |
/* |
/branches/tracing/kernel/arch/ia32/src/smp/smp.c |
---|
155,7 → 155,7 |
* Prepare new GDT for CPU in question. |
*/ |
gdt_new = (struct descriptor *) malloc(GDT_ITEMS * |
sizeof(struct descriptor), FRAME_ATOMIC); |
sizeof(struct descriptor), FRAME_ATOMIC | FRAME_LOW_4_GiB); |
if (!gdt_new) |
panic("couldn't allocate memory for GDT\n"); |
/branches/tracing/kernel/arch/ia32/src/mm/as.c |
---|
39,9 → 39,7 |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
#ifndef __OBJC__ |
as_operations = &as_pt_operations; |
#endif |
} |
/** @} |
/branches/tracing/kernel/arch/ia32/src/userspace.c |
---|
70,6 → 70,10 |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
/* %ebx is defined to hold pcb_ptr - set it to 0 */ |
"xorl %%ebx, %%ebx\n" |
"iret\n" |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
/branches/tracing/kernel/arch/ia32/src/drivers/ega.c |
---|
93,12 → 93,6 |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM); |
sysinfo_set_item_val("fb.address.color", NULL, PAGE_COLOR((uintptr_t) |
videoram)); |
#ifndef CONFIG_FB |
putchar('\n'); |
#endif |
} |
static void ega_display_char(char ch) |