/branches/dynload/kernel/test/mm/falloc2.c |
---|
55,7 → 55,7 |
uint8_t val = THREAD->tid % THREADS; |
index_t k; |
uintptr_t * frames = (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), FRAME_ATOMIC); |
void **frames = (void **) malloc(MAX_FRAMES * sizeof(void *), FRAME_ATOMIC); |
if (frames == NULL) { |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Unable to allocate frames\n", THREAD->tid, CPU->id); |
73,7 → 73,7 |
allocated = 0; |
for (i = 0; i < (MAX_FRAMES >> order); i++) { |
frames[allocated] = (uintptr_t)frame_alloc(order, FRAME_ATOMIC | FRAME_KA); |
frames[allocated] = frame_alloc(order, FRAME_ATOMIC | FRAME_KA); |
if (frames[allocated]) { |
memsetb(frames[allocated], FRAME_SIZE << order, val); |
allocated++; |
/branches/dynload/kernel/test/mm/slab1.c |
---|
53,7 → 53,7 |
for (i = 0; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
memsetb((uintptr_t) data[i], size, 0); |
memsetb(data[i], size, 0); |
} |
if (!quiet) { |
71,7 → 71,7 |
for (i = 0; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
memsetb((uintptr_t) data[i], size, 0); |
memsetb(data[i], size, 0); |
} |
if (!quiet) { |
89,7 → 89,7 |
for (i = count / 2; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
memsetb((uintptr_t) data[i], size, 0); |
memsetb(data[i], size, 0); |
} |
if (!quiet) { |
151,7 → 151,7 |
} |
if (!sh_quiet) |
printf("Thread #" PRIu64 " finished\n", THREAD->tid); |
printf("Thread #%" PRIu64 " finished\n", THREAD->tid); |
semaphore_up(&thr_sem); |
} |
/branches/dynload/kernel/test/mm/slab2.c |
---|
68,8 → 68,8 |
slab_free(cache2, data2); |
break; |
} |
memsetb((uintptr_t) data1, ITEM_SIZE, 0); |
memsetb((uintptr_t) data2, ITEM_SIZE, 0); |
memsetb(data1, ITEM_SIZE, 0); |
memsetb(data2, ITEM_SIZE, 0); |
*((void **) data1) = olddata1; |
*((void **) data2) = olddata2; |
olddata1 = data1; |
100,7 → 100,7 |
printf("Incorrect memory size - use another test."); |
return; |
} |
memsetb((uintptr_t) data1, ITEM_SIZE, 0); |
memsetb(data1, ITEM_SIZE, 0); |
*((void **) data1) = olddata1; |
olddata1 = data1; |
} |
108,7 → 108,7 |
data1 = slab_alloc(cache1, FRAME_ATOMIC); |
if (!data1) |
break; |
memsetb((uintptr_t) data1, ITEM_SIZE, 0); |
memsetb(data1, ITEM_SIZE, 0); |
*((void **) data1) = olddata1; |
olddata1 = data1; |
} |
/branches/dynload/kernel/genarch/src/mm/page_pt.c |
---|
76,7 → 76,7 |
if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = (pte_t *)frame_alloc(PTL1_SIZE, FRAME_KA); |
memsetb((uintptr_t)newpt, FRAME_SIZE << PTL1_SIZE, 0); |
memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0); |
SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt)); |
SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
} |
85,7 → 85,7 |
if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = (pte_t *)frame_alloc(PTL2_SIZE, FRAME_KA); |
memsetb((uintptr_t)newpt, FRAME_SIZE << PTL2_SIZE, 0); |
memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0); |
SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt)); |
SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
} |
94,7 → 94,7 |
if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = (pte_t *)frame_alloc(PTL3_SIZE, FRAME_KA); |
memsetb((uintptr_t)newpt, FRAME_SIZE << PTL3_SIZE, 0); |
memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0); |
SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt)); |
SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
} |
146,7 → 146,7 |
ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page))); |
/* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */ |
memsetb((uintptr_t) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); |
memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); |
/* |
* Second, free all empty tables along the way from PTL3 down to PTL0. |
166,11 → 166,11 |
*/ |
frame_free(KA2PA((uintptr_t) ptl3)); |
if (PTL2_ENTRIES) |
memsetb((uintptr_t) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); |
memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); |
else if (PTL1_ENTRIES) |
memsetb((uintptr_t) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
else |
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
} else { |
/* |
* PTL3 is not empty. |
195,9 → 195,9 |
*/ |
frame_free(KA2PA((uintptr_t) ptl2)); |
if (PTL1_ENTRIES) |
memsetb((uintptr_t) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
else |
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
} |
else { |
/* |
223,7 → 223,7 |
* Release the frame and remove PTL1 pointer from preceding table. |
*/ |
frame_free(KA2PA((uintptr_t) ptl1)); |
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
} |
} |
/branches/dynload/kernel/genarch/src/mm/as_pt.c |
---|
103,7 → 103,7 |
table_size = FRAME_SIZE << PTL0_SIZE; |
if (flags & FLAG_AS_KERNEL) { |
memsetb((uintptr_t) dst_ptl0, table_size, 0); |
memsetb(dst_ptl0, table_size, 0); |
} else { |
uintptr_t src, dst; |
118,7 → 118,7 |
src = (uintptr_t) &src_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)]; |
dst = (uintptr_t) &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)]; |
memsetb((uintptr_t) dst_ptl0, table_size, 0); |
memsetb(dst_ptl0, table_size, 0); |
memcpy((void *) dst, (void *) src, table_size - (src - (uintptr_t) src_ptl0)); |
mutex_unlock(&AS_KERNEL->lock); |
interrupts_restore(ipl); |
/branches/dynload/kernel/generic/include/memstr.h |
---|
42,8 → 42,8 |
* Architecture independent variants. |
*/ |
extern void *_memcpy(void *dst, const void *src, size_t cnt); |
extern void _memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void _memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void _memsetb(void *dst, size_t cnt, uint8_t x); |
extern void _memsetw(void *dst, size_t cnt, uint16_t x); |
extern char *strcpy(char *dest, const char *src); |
#endif |
/branches/dynload/kernel/generic/include/console/console.h |
---|
41,6 → 41,9 |
extern chardev_t *stdin; |
extern chardev_t *stdout; |
extern void klog_init(void); |
extern void klog_update(void); |
extern uint8_t getc(chardev_t *chardev); |
uint8_t _getc(chardev_t *chardev); |
extern count_t gets(chardev_t *chardev, char *buf, size_t buflen); |
/branches/dynload/kernel/generic/include/typedefs.h |
---|
35,6 → 35,8 |
#ifndef KERN_TYPEDEFS_H_ |
#define KERN_TYPEDEFS_H_ |
#include <arch/types.h> |
#define NULL 0 |
#define false 0 |
#define true 1 |
/branches/dynload/kernel/generic/include/syscall/syscall.h |
---|
36,7 → 36,7 |
#define KERN_SYSCALL_H_ |
typedef enum { |
SYS_IO = 0, |
SYS_KLOG = 0, |
SYS_TLS_SET = 1, /* Hardcoded in AMD64, IA32 uspace - fibril.S */ |
SYS_THREAD_CREATE, |
/branches/dynload/kernel/generic/src/main/main.c |
---|
80,6 → 80,7 |
#include <adt/btree.h> |
#include <smp/smp.h> |
#include <ddi/ddi.h> |
#include <console/console.h> |
/** Global configuration structure. */ |
config_t config; |
256,6 → 257,7 |
printf("No init binaries found\n"); |
LOG_EXEC(ipc_init()); |
LOG_EXEC(klog_init()); |
/* |
* Create kernel task. |
/branches/dynload/kernel/generic/src/cpu/cpu.c |
---|
67,7 → 67,7 |
panic("malloc/cpus"); |
/* initialize everything */ |
memsetb((uintptr_t) cpus, sizeof(cpu_t) * config.cpu_count, 0); |
memsetb(cpus, sizeof(cpu_t) * config.cpu_count, 0); |
for (i = 0; i < config.cpu_count; i++) { |
cpus[i].stack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | FRAME_ATOMIC); |
/branches/dynload/kernel/generic/src/console/console.c |
---|
35,19 → 35,27 |
#include <console/console.h> |
#include <console/chardev.h> |
#include <sysinfo/sysinfo.h> |
#include <synch/waitq.h> |
#include <synch/spinlock.h> |
#include <arch/types.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <ddi/ddi.h> |
#include <ipc/irq.h> |
#include <arch.h> |
#include <func.h> |
#include <print.h> |
#include <atomic.h> |
#define KLOG_SIZE 4096 |
#define KLOG_SIZE PAGE_SIZE |
#define KLOG_LATENCY 8 |
/**< Kernel log cyclic buffer */ |
static char klog[KLOG_SIZE]; |
static char klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE))); |
/**< Kernel log initialized */ |
static bool klog_inited = false; |
/**< First kernel log characters */ |
static index_t klog_start = 0; |
/**< Number of valid kernel log characters */ |
54,7 → 62,24 |
static size_t klog_len = 0; |
/**< Number of stored (not printed) kernel log characters */ |
static size_t klog_stored = 0; |
/**< Number of stored kernel log characters for uspace */ |
static size_t klog_uspace = 0; |
/**< Kernel log spinlock */ |
SPINLOCK_INITIALIZE(klog_lock); |
/** Physical memory area used for klog buffer */ |
static parea_t klog_parea; |
/* |
* For now, we use 0 as INR. |
* However, it is therefore desirable to have architecture specific |
* definition of KLOG_VIRT_INR in the future. |
*/ |
#define KLOG_VIRT_INR 0 |
static irq_t klog_irq; |
static chardev_operations_t null_stdout_ops = { |
.suspend = NULL, |
.resume = NULL, |
67,10 → 92,58 |
.op = &null_stdout_ops |
}; |
/** Standard input character device. */ |
/** Allways refuse IRQ ownership. |
* |
* This is not a real IRQ, so we always decline. |
* |
* @return Always returns IRQ_DECLINE. |
*/ |
static irq_ownership_t klog_claim(void) |
{ |
return IRQ_DECLINE; |
} |
/** Standard input character device */ |
chardev_t *stdin = NULL; |
chardev_t *stdout = &null_stdout; |
/** Initialize kernel logging facility |
* |
* The shared area contains kernel cyclic buffer. Userspace application may |
* be notified on new data with indication of position and size |
* of the data within the circular buffer. |
*/ |
void klog_init(void) |
{ |
void *faddr = (void *) KA2PA(klog); |
ASSERT((uintptr_t) faddr % FRAME_SIZE == 0); |
ASSERT(KLOG_SIZE % FRAME_SIZE == 0); |
devno_t devno = device_assign_devno(); |
klog_parea.pbase = (uintptr_t) faddr; |
klog_parea.vbase = (uintptr_t) klog; |
klog_parea.frames = SIZE2FRAMES(KLOG_SIZE); |
klog_parea.cacheable = true; |
ddi_parea_register(&klog_parea); |
sysinfo_set_item_val("klog.faddr", NULL, (unative_t) faddr); |
sysinfo_set_item_val("klog.pages", NULL, SIZE2FRAMES(KLOG_SIZE)); |
sysinfo_set_item_val("klog.devno", NULL, devno); |
sysinfo_set_item_val("klog.inr", NULL, KLOG_VIRT_INR); |
irq_initialize(&klog_irq); |
klog_irq.devno = devno; |
klog_irq.inr = KLOG_VIRT_INR; |
klog_irq.claim = klog_claim; |
irq_register(&klog_irq); |
spinlock_lock(&klog_lock); |
klog_inited = true; |
spinlock_unlock(&klog_lock); |
} |
/** Get character from character device. Do not echo character. |
* |
* @param chardev Character device. |
160,8 → 233,22 |
return ch; |
} |
void klog_update(void) |
{ |
spinlock_lock(&klog_lock); |
if ((klog_inited) && (klog_irq.notif_cfg.notify) && (klog_uspace > 0)) { |
ipc_irq_send_msg_3(&klog_irq, klog_start, klog_len, klog_uspace); |
klog_uspace = 0; |
} |
spinlock_unlock(&klog_lock); |
} |
void putchar(char c) |
{ |
spinlock_lock(&klog_lock); |
if ((klog_stored > 0) && (stdout->op->write)) { |
/* Print charaters stored in kernel log */ |
index_t i; |
184,6 → 271,22 |
if (klog_stored < klog_len) |
klog_stored++; |
} |
/* The character is stored for uspace */ |
if (klog_uspace < klog_len) |
klog_uspace++; |
/* Check notify uspace to update */ |
bool update; |
if ((klog_uspace > KLOG_LATENCY) || (c == '\n')) |
update = true; |
else |
update = false; |
spinlock_unlock(&klog_lock); |
if (update) |
klog_update(); |
} |
/** @} |
/branches/dynload/kernel/generic/src/proc/task.c |
---|
45,6 → 45,7 |
#include <synch/spinlock.h> |
#include <synch/waitq.h> |
#include <arch.h> |
#include <arch/barrier.h> |
#include <panic.h> |
#include <adt/avl.h> |
#include <adt/btree.h> |
447,8 → 448,16 |
int rc = copy_from_uspace(kimage, image, size); |
if (rc != EOK) |
return rc; |
/* |
* Not very efficient and it would be better to call it on code only, |
* but this whole function is a temporary hack anyway and one day it |
* will go in favor of the userspace dynamic loader. |
*/ |
smc_coherence_block(kimage, size); |
uspace_arg_t *kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
uspace_arg_t *kernel_uarg; |
kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
if (kernel_uarg == NULL) { |
free(kimage); |
return ENOMEM; |
477,9 → 486,9 |
} |
as_area_t *area = as_area_create(as, |
AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, |
LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, |
AS_AREA_ATTR_NONE, &anon_backend, NULL); |
AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, |
LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, |
AS_AREA_ATTR_NONE, &anon_backend, NULL); |
if (area == NULL) { |
as_destroy(as); |
free(kernel_uarg); |
499,7 → 508,7 |
cap_set(task, cap_get(TASK)); |
thread_t *thread = thread_create(uinit, kernel_uarg, task, |
THREAD_FLAG_USPACE, "user", false); |
THREAD_FLAG_USPACE, "user", false); |
if (thread == NULL) { |
task_destroy(task); |
as_destroy(as); |
630,15 → 639,15 |
order(task_get_accounting(t), &cycles, &suffix); |
#ifdef __32_BITS__ |
printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %7ld %6ld", |
t->taskid, t->name, t->context, t, t->as, cycles, suffix, |
atomic_get(&t->refcount), atomic_get(&t->active_calls)); |
printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %10p %10p %9" PRIu64 |
"%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles, |
suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls)); |
#endif |
#ifdef __64_BITS__ |
printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %7ld %6ld", |
t->taskid, t->name, t->context, t, t->as, cycles, suffix, |
atomic_get(&t->refcount), atomic_get(&t->active_calls)); |
printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %18p %18p %9" PRIu64 |
"%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles, |
suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls)); |
#endif |
for (j = 0; j < IPC_MAX_PHONES; j++) { |
662,16 → 671,16 |
#ifdef __32_BITS__ |
printf("taskid name ctx address as " |
"cycles threads calls callee\n"); |
"cycles threads calls callee\n"); |
printf("------ ---------- --- ---------- ---------- " |
"---------- ------- ------ ------>\n"); |
"---------- ------- ------ ------>\n"); |
#endif |
#ifdef __64_BITS__ |
printf("taskid name ctx address as " |
"cycles threads calls callee\n"); |
"cycles threads calls callee\n"); |
printf("------ ---------- --- ------------------ ------------------ " |
"---------- ------- ------ ------>\n"); |
"---------- ------- ------ ------>\n"); |
#endif |
avltree_walk(&tasks_tree, task_print_walker, NULL); |
/branches/dynload/kernel/generic/src/proc/thread.c |
---|
293,8 → 293,7 |
return NULL; |
/* Not needed, but good for debugging */ |
memsetb((uintptr_t) t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, |
0); |
memsetb(t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0); |
ipl = interrupts_disable(); |
spinlock_lock(&tidlock); |
/branches/dynload/kernel/generic/src/lib/memstr.c |
---|
87,7 → 87,7 |
* @param x Value to fill. |
* |
*/ |
void _memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
void _memsetb(void *dst, size_t cnt, uint8_t x) |
{ |
unsigned int i; |
uint8_t *p = (uint8_t *) dst; |
106,7 → 106,7 |
* @param x Value to fill. |
* |
*/ |
void _memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
void _memsetw(void *dst, size_t cnt, uint16_t x) |
{ |
unsigned int i; |
uint16_t *p = (uint16_t *) dst; |
/branches/dynload/kernel/generic/src/lib/objc_ext.c |
---|
161,7 → 161,7 |
void *memset(void *s, int c, size_t n) |
{ |
memsetb((uintptr_t) s, n, c); |
memsetb(s, n, c); |
return s; |
} |
/branches/dynload/kernel/generic/src/adt/hash_table.c |
---|
63,7 → 63,7 |
if (!h->entry) { |
panic("cannot allocate memory for hash table\n"); |
} |
memsetb((uintptr_t) h->entry, m * sizeof(link_t), 0); |
memsetb(h->entry, m * sizeof(link_t), 0); |
for (i = 0; i < m; i++) |
list_initialize(&h->entry[i]); |
/branches/dynload/kernel/generic/src/mm/slab.c |
---|
559,8 → 559,7 |
cache->mag_cache = malloc(sizeof(slab_mag_cache_t) * config.cpu_count,0); |
for (i = 0; i < config.cpu_count; i++) { |
memsetb((uintptr_t)&cache->mag_cache[i], |
sizeof(cache->mag_cache[i]), 0); |
memsetb(&cache->mag_cache[i], sizeof(cache->mag_cache[i]), 0); |
spinlock_initialize(&cache->mag_cache[i].lock, "slab_maglock_cpu"); |
} |
} |
578,7 → 577,7 |
int pages; |
ipl_t ipl; |
memsetb((uintptr_t)cache, sizeof(*cache), 0); |
memsetb(cache, sizeof(*cache), 0); |
cache->name = name; |
if (align < sizeof(unative_t)) |
/branches/dynload/kernel/generic/src/mm/backend_anon.c |
---|
113,7 → 113,7 |
} |
if (allocate) { |
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
/* |
144,7 → 144,7 |
* the different causes |
*/ |
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
} |
/branches/dynload/kernel/generic/src/mm/as.c |
---|
324,8 → 324,7 |
if (backend_data) |
a->backend_data = *backend_data; |
else |
memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), |
0); |
memsetb(&a->backend_data, sizeof(a->backend_data), 0); |
btree_create(&a->used_space); |
/branches/dynload/kernel/generic/src/mm/page.c |
---|
40,11 → 40,28 |
* They however, define the single interface. |
*/ |
/* |
* Note on memory prefetching and updating memory mappings, also described in: |
* AMD x86-64 Architecture Programmer's Manual, Volume 2, System Programming, |
* 7.2.1 Special Coherency Considerations. |
* |
* The processor which modifies a page table mapping can access prefetched data |
* from the old mapping. In order to prevent this, we place a memory barrier |
* after a mapping is updated. |
* |
* We assume that the other processors are either not using the mapping yet |
* (i.e. during the bootstrap) or are executing the TLB shootdown code. While |
* we don't care much about the former case, the processors in the latter case |
* will do an implicit serialization by virtue of running the TLB shootdown |
* interrupt handler. |
*/ |
#include <mm/page.h> |
#include <arch/mm/page.h> |
#include <arch/mm/asid.h> |
#include <mm/as.h> |
#include <mm/frame.h> |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <memstr.h> |
65,8 → 82,8 |
* considering possible crossings |
* of page boundaries. |
* |
* @param s Address of the structure. |
* @param size Size of the structure. |
* @param s Address of the structure. |
* @param size Size of the structure. |
*/ |
void map_structure(uintptr_t s, size_t size) |
{ |
76,8 → 93,11 |
cnt = length / PAGE_SIZE + (length % PAGE_SIZE > 0); |
for (i = 0; i < cnt; i++) |
page_mapping_insert(AS_KERNEL, s + i * PAGE_SIZE, s + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, s + i * PAGE_SIZE, |
s + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE); |
/* Repel prefetched accesses to the old mapping. */ |
memory_barrier(); |
} |
/** Insert mapping of page to frame. |
87,10 → 107,11 |
* |
* The page table must be locked and interrupts must be disabled. |
* |
* @param as Address space to wich page belongs. |
* @param page Virtual address of the page to be mapped. |
* @param frame Physical address of memory frame to which the mapping is done. |
* @param flags Flags to be used for mapping. |
* @param as Address space to wich page belongs. |
* @param page Virtual address of the page to be mapped. |
* @param frame Physical address of memory frame to which the mapping is |
* done. |
* @param flags Flags to be used for mapping. |
*/ |
void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags) |
{ |
98,6 → 119,9 |
ASSERT(page_mapping_operations->mapping_insert); |
page_mapping_operations->mapping_insert(as, page, frame, flags); |
/* Repel prefetched accesses to the old mapping. */ |
memory_barrier(); |
} |
/** Remove mapping of page. |
108,8 → 132,8 |
* |
* The page table must be locked and interrupts must be disabled. |
* |
* @param as Address space to wich page belongs. |
* @param page Virtual address of the page to be demapped. |
* @param as Address space to wich page belongs. |
* @param page Virtual address of the page to be demapped. |
*/ |
void page_mapping_remove(as_t *as, uintptr_t page) |
{ |
117,6 → 141,9 |
ASSERT(page_mapping_operations->mapping_remove); |
page_mapping_operations->mapping_remove(as, page); |
/* Repel prefetched accesses to the old mapping. */ |
memory_barrier(); |
} |
/** Find mapping for virtual page |
125,10 → 152,11 |
* |
* The page table must be locked and interrupts must be disabled. |
* |
* @param as Address space to wich page belongs. |
* @param page Virtual page. |
* @param as Address space to wich page belongs. |
* @param page Virtual page. |
* |
* @return NULL if there is no such mapping; requested mapping otherwise. |
* @return NULL if there is no such mapping; requested mapping |
* otherwise. |
*/ |
pte_t *page_mapping_find(as_t *as, uintptr_t page) |
{ |
/branches/dynload/kernel/generic/src/mm/backend_elf.c |
---|
48,6 → 48,7 |
#include <memstr.h> |
#include <macros.h> |
#include <arch.h> |
#include <arch/barrier.h> |
#ifdef CONFIG_VIRT_IDX_DCACHE |
#include <arch/mm/cache.h> |
67,12 → 68,13 |
* |
* The address space area and page tables must be already locked. |
* |
* @param area Pointer to the address space area. |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* @param area Pointer to the address space area. |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. |
* read/write/exec). |
* |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. |
* serviced). |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK |
* on success (i.e. serviced). |
*/ |
int elf_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access) |
{ |
150,6 → 152,10 |
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0); |
memcpy((void *) PA2KA(frame), |
(void *) (base + i * FRAME_SIZE), FRAME_SIZE); |
if (entry->p_flags & PF_X) { |
smc_coherence_block((void *) PA2KA(frame), |
FRAME_SIZE); |
} |
dirty = true; |
} else { |
frame = KA2PA(base + i * FRAME_SIZE); |
162,7 → 168,7 |
* and cleared. |
*/ |
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
} else { |
size_t pad_lo, pad_hi; |
187,8 → 193,13 |
memcpy((void *) (PA2KA(frame) + pad_lo), |
(void *) (base + i * FRAME_SIZE + pad_lo), |
FRAME_SIZE - pad_lo - pad_hi); |
memsetb(PA2KA(frame), pad_lo, 0); |
memsetb(PA2KA(frame) + FRAME_SIZE - pad_hi, pad_hi, 0); |
if (entry->p_flags & PF_X) { |
smc_coherence_block((void *) (PA2KA(frame) + pad_lo), |
FRAME_SIZE - pad_lo - pad_hi); |
} |
memsetb((void *) PA2KA(frame), pad_lo, 0); |
memsetb((void *) (PA2KA(frame) + FRAME_SIZE - pad_hi), pad_hi, |
0); |
dirty = true; |
} |
212,9 → 223,10 |
* |
* The address space area and page tables must be already locked. |
* |
* @param area Pointer to the address space area. |
* @param page Page that is mapped to frame. Must be aligned to PAGE_SIZE. |
* @param frame Frame to be released. |
* @param area Pointer to the address space area. |
* @param page Page that is mapped to frame. Must be aligned to |
* PAGE_SIZE. |
* @param frame Frame to be released. |
* |
*/ |
void elf_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame) |
257,7 → 269,7 |
* |
* The address space and address space area must be locked prior to the call. |
* |
* @param area Address space area. |
* @param area Address space area. |
*/ |
void elf_share(as_area_t *area) |
{ |
/branches/dynload/kernel/generic/src/syscall/syscall.c |
---|
57,7 → 57,7 |
* Print to kernel log. |
* |
*/ |
static unative_t sys_io(int fd, const void * buf, size_t count) |
static unative_t sys_klog(int fd, const void * buf, size_t count) |
{ |
size_t i; |
char *data; |
65,20 → 65,23 |
if (count > PAGE_SIZE) |
return ELIMIT; |
data = (char *) malloc(count, 0); |
if (!data) |
return ENOMEM; |
rc = copy_from_uspace(data, buf, count); |
if (rc) { |
if (count > 0) { |
data = (char *) malloc(count, 0); |
if (!data) |
return ENOMEM; |
rc = copy_from_uspace(data, buf, count); |
if (rc) { |
free(data); |
return rc; |
} |
for (i = 0; i < count; i++) |
putchar(data[i]); |
free(data); |
return rc; |
} |
for (i = 0; i < count; i++) |
putchar(data[i]); |
free(data); |
} else |
klog_update(); |
return count; |
} |
118,7 → 121,7 |
} |
syshandler_t syscall_table[SYSCALL_END] = { |
(syshandler_t) sys_io, |
(syshandler_t) sys_klog, |
(syshandler_t) sys_tls_set, |
/* Thread and task related syscalls. */ |
/branches/dynload/kernel/generic/src/ipc/ipc.c |
---|
66,7 → 66,7 |
*/ |
static void _ipc_call_init(call_t *call) |
{ |
memsetb((uintptr_t) call, sizeof(*call), 0); |
memsetb(call, sizeof(*call), 0); |
call->callerbox = &TASK->answerbox; |
call->sender = TASK; |
call->buffer = NULL; |
/branches/dynload/kernel/arch/sparc64/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/branches/dynload/kernel/arch/sparc64/include/mm/cache_spec.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2008 Jakub Jermar |
* 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 sparc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_sparc64_CACHE_SPEC_H_ |
#define KERN_sparc64_CACHE_SPEC_H_ |
/* |
* The following macros are valid for the following processors: |
* |
* UltraSPARC, UltraSPARC II, UltraSPARC IIi |
* |
* Should we support other UltraSPARC processors, we need to make sure that |
* the macros are defined correctly for them. |
*/ |
#define DCACHE_SIZE (16 * 1024) |
#define DCACHE_LINE_SIZE 32 |
#define ICACHE_SIZE (16 * 1024) |
#define ICACHE_WAYS 2 |
#define ICACHE_LINE_SIZE 32 |
#endif |
/** @} |
*/ |
/branches/dynload/kernel/arch/sparc64/include/mm/tlb.h |
---|
160,7 → 160,7 |
static inline void mmu_primary_context_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v); |
flush(); |
flush_pipeline(); |
} |
/** Read MMU Secondary Context Register. |
179,7 → 179,7 |
static inline void mmu_secondary_context_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v); |
flush(); |
flush_pipeline(); |
} |
/** Read IMMU TLB Data Access Register. |
209,7 → 209,7 |
reg.value = 0; |
reg.tlb_entry = entry; |
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value); |
flush(); |
flush_pipeline(); |
} |
/** Read DMMU TLB Data Access Register. |
279,7 → 279,7 |
static inline void itlb_tag_access_write(uint64_t v) |
{ |
asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v); |
flush(); |
flush_pipeline(); |
} |
/** Read IMMU TLB Tag Access Register. |
318,7 → 318,7 |
static inline void itlb_data_in_write(uint64_t v) |
{ |
asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v); |
flush(); |
flush_pipeline(); |
} |
/** Write DMMU TLB Data in Register. |
347,7 → 347,7 |
static inline void itlb_sfsr_write(uint64_t v) |
{ |
asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v); |
flush(); |
flush_pipeline(); |
} |
/** Read DTLB Synchronous Fault Status Register. |
400,7 → 400,7 |
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the |
* address within the |
* ASI */ |
flush(); |
flush_pipeline(); |
} |
/** Perform DMMU TLB Demap Operation. |
/branches/dynload/kernel/arch/sparc64/include/barrier.h |
---|
57,8 → 57,11 |
#define write_barrier() \ |
asm volatile ("membar #StoreStore\n" ::: "memory") |
/** Flush Instruction Memory instruction. */ |
static inline void flush(void) |
#define flush(a) \ |
asm volatile ("flush %0\n" :: "r" ((a)) : "memory") |
/** Flush Instruction pipeline. */ |
static inline void flush_pipeline(void) |
{ |
/* |
* The FLUSH instruction takes address parameter. |
79,6 → 82,21 |
asm volatile ("membar #Sync\n"); |
} |
#define smc_coherence(a) \ |
{ \ |
write_barrier(); \ |
flush((a)); \ |
} |
#define FLUSH_INVAL_MIN 4 |
#define smc_coherence_block(a, l) \ |
{ \ |
unsigned long i; \ |
write_barrier(); \ |
for (i = 0; i < (l); i += FLUSH_INVAL_MIN) \ |
flush((void *)(a) + i); \ |
} |
#endif |
/** @} |
/branches/dynload/kernel/arch/sparc64/src/mm/as.c |
---|
76,7 → 76,7 |
as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT * |
sizeof(tsb_entry_t)); |
memsetb((uintptr_t) as->arch.itsb, |
memsetb(as->arch.itsb, |
(ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0); |
#endif |
return 0; |
/branches/dynload/kernel/arch/sparc64/src/mm/cache.S |
---|
27,10 → 27,8 |
*/ |
#include <arch/arch.h> |
#include <arch/mm/cache_spec.h> |
#define DCACHE_SIZE (16 * 1024) |
#define DCACHE_LINE_SIZE 32 |
#define DCACHE_TAG_SHIFT 2 |
.register %g2, #scratch |
/branches/dynload/kernel/arch/ia64/include/types.h |
---|
65,6 → 65,29 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
#define PRIp "lx" /**< Format for uintptr_t. */ |
#define PRIs "lu" /**< Format for size_t. */ |
#define PRIc "lu" /**< Format for count_t. */ |
#define PRIi "lu" /**< Format for index_t. */ |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
#define PRId32 "d" /**< Format for int32_t. */ |
#define PRId64 "ld" /**< 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 "lu" /**< 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 "lx" /**< Format for hexadecimal (u)int64_t. */ |
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */ |
#endif |
/** @} |
/branches/dynload/kernel/arch/ia64/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/branches/dynload/kernel/arch/ia64/include/barrier.h |
---|
45,9 → 45,33 |
#define read_barrier() memory_barrier() |
#define write_barrier() memory_barrier() |
#define srlz_i() asm volatile (";; srlz.i ;;\n" ::: "memory") |
#define srlz_d() asm volatile (";; srlz.d\n" ::: "memory") |
#define srlz_i() \ |
asm volatile (";; srlz.i ;;\n" ::: "memory") |
#define srlz_d() \ |
asm volatile (";; srlz.d\n" ::: "memory") |
#define fc_i(a) \ |
asm volatile ("fc.i %0\n" :: "r" ((a)) : "memory") |
#define sync_i() \ |
asm volatile (";; sync.i\n" ::: "memory") |
#define smc_coherence(a) \ |
{ \ |
fc_i((a)); \ |
sync_i(); \ |
srlz_i(); \ |
} |
#define FC_INVAL_MIN 32 |
#define smc_coherence_block(a, l) \ |
{ \ |
unsigned long i; \ |
for (i = 0; i < (l); i += FC_INVAL_MIN) \ |
fc_i((void *)(a) + i); \ |
sync_i(); \ |
srlz_i(); \ |
} |
#endif |
/** @} |
/branches/dynload/kernel/arch/ia64/src/mm/vhpt.c |
---|
81,7 → 81,7 |
void vhpt_invalidate_all() |
{ |
memsetb((uintptr_t) vhpt_base, 1 << VHPT_WIDTH, 0); |
memsetb(vhpt_base, 1 << VHPT_WIDTH, 0); |
} |
void vhpt_invalidate_asid(asid_t asid) |
/branches/dynload/kernel/arch/ia64/src/drivers/ega.c |
---|
71,7 → 71,7 |
/* |
* Clear the screen. |
*/ |
_memsetw((uintptr_t) videoram, SCREEN, 0x0720); |
_memsetw(videoram, SCREEN, 0x0720); |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
102,7 → 102,7 |
return; |
memcpy((void *) videoram, (void *) (videoram + ROW * 2), (SCREEN - ROW) * 2); |
_memsetw((uintptr_t) (videoram + (SCREEN - ROW) * 2), ROW, 0x0720); |
_memsetw(videoram + (SCREEN - ROW) * 2, ROW, 0x0720); |
ega_cursor = ega_cursor - ROW; |
} |
/branches/dynload/kernel/arch/arm32/include/types.h |
---|
64,7 → 64,29 |
typedef uint32_t unative_t; |
typedef int32_t native_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. */ |
#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. |
* |
* We have different structs for level 0 and level 1 page table entries. |
/branches/dynload/kernel/arch/arm32/include/memstr.h |
---|
38,10 → 38,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/branches/dynload/kernel/arch/arm32/include/barrier.h |
---|
46,6 → 46,9 |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
#endif |
/** @} |
/branches/dynload/kernel/arch/arm32/Makefile.inc |
---|
37,9 → 37,9 |
KERNEL_LOAD_ADDRESS = 0x80200000 |
ifeq ($(MACHINE), gxemul_testarm) |
# ifeq ($(MACHINE), gxemul_testarm) |
DMACHINE = MACHINE_GXEMUL_TESTARM |
endif |
# endif |
ATSIGN = % |
90,7 → 90,7 |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/mm/page_fault.c |
ifeq ($(MACHINE), gxemul_testarm) |
# ifeq ($(MACHINE), gxemul_testarm) |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/gxemul.c |
endif |
# endif |
/branches/dynload/kernel/arch/arm32/src/exception.c |
---|
40,6 → 40,7 |
#include <interrupt.h> |
#include <arch/machine.h> |
#include <arch/mm/page_fault.h> |
#include <arch/barrier.h> |
#include <print.h> |
#include <syscall/syscall.h> |
209,7 → 210,7 |
* |
* Addresses of handlers are stored in memory following exception vectors. |
*/ |
static void install_handler (unsigned handler_addr, unsigned* vector) |
static void install_handler(unsigned handler_addr, unsigned *vector) |
{ |
/* relative address (related to exc. vector) of the word |
* where handler's address is stored |
219,6 → 220,7 |
/* make it LDR instruction and store at exception vector */ |
*vector = handler_address_ptr | LDR_OPCODE; |
smc_coherence(*vector); |
/* store handler's address */ |
*(vector + EXC_VECTORS) = handler_addr; |
226,31 → 228,31 |
} |
/** Low-level Reset Exception handler. */ |
static void reset_exception_entry() |
static void reset_exception_entry(void) |
{ |
PROCESS_EXCEPTION(EXC_RESET); |
} |
/** Low-level Software Interrupt Exception handler. */ |
static void swi_exception_entry() |
static void swi_exception_entry(void) |
{ |
PROCESS_EXCEPTION(EXC_SWI); |
} |
/** Low-level Undefined Instruction Exception handler. */ |
static void undef_instr_exception_entry() |
static void undef_instr_exception_entry(void) |
{ |
PROCESS_EXCEPTION(EXC_UNDEF_INSTR); |
} |
/** Low-level Fast Interrupt Exception handler. */ |
static void fiq_exception_entry() |
static void fiq_exception_entry(void) |
{ |
PROCESS_EXCEPTION(EXC_FIQ); |
} |
/** Low-level Prefetch Abort Exception handler. */ |
static void prefetch_abort_exception_entry() |
static void prefetch_abort_exception_entry(void) |
{ |
asm("sub lr, lr, #4"); |
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT); |
257,7 → 259,7 |
} |
/** Low-level Data Abort Exception handler. */ |
static void data_abort_exception_entry() |
static void data_abort_exception_entry(void) |
{ |
asm("sub lr, lr, #8"); |
PROCESS_EXCEPTION(EXC_DATA_ABORT); |
269,7 → 271,7 |
* because of possible occurence of nested interrupt exception, which |
* would overwrite (and thus spoil) stack pointer. |
*/ |
static void irq_exception_entry() |
static void irq_exception_entry(void) |
{ |
asm("sub lr, lr, #4"); |
setup_stack_and_save_regs(); |
/branches/dynload/kernel/arch/arm32/src/mm/page_fault.c |
---|
40,6 → 40,7 |
#include <genarch/mm/page_pt.h> |
#include <arch.h> |
#include <interrupt.h> |
#include <print.h> |
/** Returns value stored in fault status register. |
* |
/branches/dynload/kernel/arch/ppc32/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/branches/dynload/kernel/arch/ppc32/include/barrier.h |
---|
42,6 → 42,43 |
#define read_barrier() asm volatile ("sync" ::: "memory") |
#define write_barrier() asm volatile ("eieio" ::: "memory") |
/* |
* The IMB sequence used here is valid for all possible cache models |
* on uniprocessor. SMP might require a different sequence. |
* See PowerPC Programming Environment for 32-Bit Microprocessors, |
* chapter 5.1.5.2 |
*/ |
static inline void smc_coherence(void *addr) |
{ |
asm volatile ( |
"dcbst 0, %0\n" |
"sync\n" |
"icbi 0, %0\n" |
"isync\n" |
:: "r" (addr) |
); |
} |
#define COHERENCE_INVAL_MIN 4 |
static inline void smc_coherence_block(void *addr, unsigned long len) |
{ |
unsigned long i; |
for (i = 0; i < len; i += COHERENCE_INVAL_MIN) { |
asm volatile ("dcbst 0, %0\n" :: "r" (addr + i)); |
} |
asm volatile ("sync"); |
for (i = 0; i < len; i += COHERENCE_INVAL_MIN) { |
asm volatile ("icbi 0, %0\n" :: "r" (addr + i)); |
} |
asm volatile ("isync"); |
} |
#endif |
/** @} |
/branches/dynload/kernel/arch/ia32xen/src/ia32xen.c |
---|
69,7 → 69,7 |
void arch_pre_main(void) |
{ |
pte_t pte; |
memsetb((uintptr_t) &pte, sizeof(pte), 0); |
memsetb(&pte, sizeof(pte), 0); |
pte.present = 1; |
pte.writeable = 1; |
103,7 → 103,7 |
uintptr_t tpa = PFN2ADDR(meminfo.start + meminfo.reserved); |
uintptr_t tva = PA2KA(tpa); |
memsetb(tva, PAGE_SIZE, 0); |
memsetb((void *) tva, PAGE_SIZE, 0); |
pte_t *tptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(tva))); |
SET_FRAME_ADDRESS(tptl3, PTL3_INDEX(tva), 0); |
/branches/dynload/kernel/arch/ia32xen/src/pm.c |
---|
98,7 → 98,7 |
void tss_initialize(tss_t *t) |
{ |
memsetb((uintptr_t) t, sizeof(struct tss), 0); |
memsetb(t, sizeof(struct tss), 0); |
} |
static void trap(void) |
/branches/dynload/kernel/arch/ia32xen/src/smp/smp.c |
---|
146,7 → 146,7 |
panic("couldn't allocate memory for GDT\n"); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0); |
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0); |
gdtr.base = (uintptr_t) gdt_new; |
if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { |
/branches/dynload/kernel/arch/amd64/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/branches/dynload/kernel/arch/amd64/src/pm.c |
---|
155,7 → 155,7 |
void tss_initialize(tss_t *t) |
{ |
memsetb((uintptr_t) t, sizeof(tss_t), 0); |
memsetb(t, sizeof(tss_t), 0); |
} |
/* |
239,7 → 239,7 |
preemption_disable(); |
ipl_t ipl = interrupts_disable(); |
memsetb((uintptr_t) idt, sizeof(idt), 0); |
memsetb(idt, sizeof(idt), 0); |
idtr_load(&idtr); |
interrupts_restore(ipl); |
/branches/dynload/kernel/arch/amd64/src/debugger.c |
---|
122,13 → 122,15 |
symbol = get_symtab_entry(breakpoints[i].address); |
#ifdef __32_BITS__ |
printf("%-2u %-5d %#10zx %s\n", i, breakpoints[i].counter, |
breakpoints[i].address, symbol); |
printf("%-2u %-5d %#10zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
#ifdef __64_BITS__ |
printf("%-2u %-5d %#18zx %s\n", i, breakpoints[i].counter, |
breakpoints[i].address, symbol); |
printf("%-2u %-5d %#18zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
} |
184,7 → 186,7 |
} |
/* Enable global breakpoint */ |
dr7 |= 0x2 << (curidx*2); |
dr7 |= 0x2 << (curidx * 2); |
write_dr7(dr7); |
256,15 → 258,15 |
if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) { |
if (*((unative_t *) breakpoints[slot].address) != 0) |
return; |
printf("**** Found ZERO on address %lx (slot %d) ****\n", |
breakpoints[slot].address, slot); |
printf("*** Found ZERO on address %lx (slot %d) ***\n", |
breakpoints[slot].address, slot); |
} else { |
printf("Data watchpoint - new data: %lx\n", |
*((unative_t *) breakpoints[slot].address)); |
*((unative_t *) breakpoints[slot].address)); |
} |
} |
printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate), |
get_symtab_entry(getip(istate))); |
get_symtab_entry(getip(istate))); |
printf("***Type 'exit' to exit kconsole.\n"); |
atomic_set(&haltstate,1); |
kconsole((void *) "debug"); |
357,7 → 359,9 |
} |
#ifdef CONFIG_SMP |
static void debug_ipi(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
static void |
debug_ipi(int n __attribute__((unused)), |
istate_t *istate __attribute__((unused))) |
{ |
int i; |
373,7 → 377,7 |
{ |
int i; |
for (i=0; i<BKPOINTS_MAX; i++) |
for (i = 0; i < BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
cmd_initialize(&bkpts_info); |
394,11 → 398,9 |
panic("could not register command %s\n", addwatchp_info.name); |
#endif |
exc_register(VECTOR_DEBUG, "debugger", |
debug_exception); |
exc_register(VECTOR_DEBUG, "debugger", debug_exception); |
#ifdef CONFIG_SMP |
exc_register(VECTOR_DEBUG_IPI, "debugger_smp", |
debug_ipi); |
exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi); |
#endif |
} |
/branches/dynload/kernel/arch/ppc64/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/branches/dynload/kernel/arch/ppc64/include/barrier.h |
---|
38,10 → 38,13 |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("sync" ::: "memory") |
#define read_barrier() asm volatile ("sync" ::: "memory") |
#define write_barrier() asm volatile ("eieio" ::: "memory") |
#define memory_barrier() asm volatile ("sync" ::: "memory") |
#define read_barrier() asm volatile ("sync" ::: "memory") |
#define write_barrier() asm volatile ("eieio" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
#endif |
/** @} |
/branches/dynload/kernel/arch/ppc64/src/mm/page.c |
---|
252,7 → 252,7 |
void pht_init(void) |
{ |
memsetb((uintptr_t) phte, 1 << PHT_BITS, 0); |
memsetb(phte, 1 << PHT_BITS, 0); |
} |
/branches/dynload/kernel/arch/mips32/include/types.h |
---|
57,6 → 57,29 |
typedef uint32_t unative_t; |
typedef int32_t native_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. */ |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
#define PRId32 "ld" /**< 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 g : 1; /**< Global bit. */ |
/branches/dynload/kernel/arch/mips32/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/branches/dynload/kernel/arch/mips32/include/barrier.h |
---|
45,6 → 45,9 |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
#endif |
/** @} |
/branches/dynload/kernel/arch/mips32/src/mips32.c |
---|
50,6 → 50,7 |
#include <arch/interrupt.h> |
#include <arch/drivers/arc.h> |
#include <console/chardev.h> |
#include <arch/barrier.h> |
#include <arch/debugger.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
100,14 → 101,18 |
/* Copy the exception vectors to the right places */ |
memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE); |
smc_coherence_block(TLB_EXC, EXCEPTION_JUMP_SIZE); |
memcpy(NORM_EXC, (char *) exception_entry, EXCEPTION_JUMP_SIZE); |
smc_coherence_block(NORM_EXC, EXCEPTION_JUMP_SIZE); |
memcpy(CACHE_EXC, (char *) cache_error_entry, EXCEPTION_JUMP_SIZE); |
smc_coherence_block(CACHE_EXC, EXCEPTION_JUMP_SIZE); |
/* |
* Switch to BEV normal level so that exception vectors point to the kernel. |
* Clear the error level. |
* Switch to BEV normal level so that exception vectors point to the |
* kernel. Clear the error level. |
*/ |
cp0_status_write(cp0_status_read() & ~(cp0_status_bev_bootstrap_bit|cp0_status_erl_error_bit)); |
cp0_status_write(cp0_status_read() & |
~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit)); |
/* |
* Mask all interrupts |
122,7 → 127,8 |
interrupt_init(); |
console_init(device_assign_devno()); |
#ifdef CONFIG_FB |
fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8); // gxemul framebuffer |
/* GXemul framebuffer */ |
fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8); |
#endif |
sysinfo_set_item_val("machine." STRING(MACHINE), NULL, 1); |
} |
143,13 → 149,14 |
{ |
/* EXL = 1, UM = 1, IE = 1 */ |
cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit | |
cp0_status_um_bit | cp0_status_ie_enabled_bit)); |
cp0_status_um_bit | cp0_status_ie_enabled_bit)); |
cp0_epc_write((uintptr_t) kernel_uarg->uspace_entry); |
userspace_asm(((uintptr_t) kernel_uarg->uspace_stack + PAGE_SIZE), |
(uintptr_t) kernel_uarg->uspace_uarg, |
(uintptr_t) kernel_uarg->uspace_entry); |
(uintptr_t) kernel_uarg->uspace_uarg, |
(uintptr_t) kernel_uarg->uspace_entry); |
while (1); |
while (1) |
; |
} |
/** Perform mips32 specific tasks needed before the new task is run. */ |
160,7 → 167,8 |
/** Perform mips32 specific tasks needed before the new thread is scheduled. */ |
void before_thread_runs_arch(void) |
{ |
supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA]; |
supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
SP_DELTA]; |
} |
void after_thread_ran_arch(void) |
182,7 → 190,8 |
if (!arc_reboot()) |
___halt(); |
while (1); |
while (1) |
; |
} |
/** @} |
/branches/dynload/kernel/arch/mips32/src/debugger.c |
---|
33,6 → 33,7 |
*/ |
#include <arch/debugger.h> |
#include <arch/barrier.h> |
#include <memstr.h> |
#include <console/kconsole.h> |
#include <console/cmd.h> |
72,7 → 73,8 |
}; |
static cmd_info_t addbkpt_info = { |
.name = "addbkpt", |
.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch insts unsupported.", |
.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch " |
"insts unsupported.", |
.func = cmd_add_breakpoint, |
.argc = 1, |
.argv = &add_argv |
84,7 → 86,8 |
}; |
static cmd_info_t addbkpte_info = { |
.name = "addbkpte", |
.description = "addebkpte <&symbol> <&func> - new bkpoint. Call func(or Nothing if 0).", |
.description = "addebkpte <&symbol> <&func> - new bkpoint. Call " |
"func(or Nothing if 0).", |
.func = cmd_add_breakpoint, |
.argc = 2, |
.argv = adde_argv |
93,7 → 96,7 |
static struct { |
uint32_t andmask; |
uint32_t value; |
}jmpinstr[] = { |
} jmpinstr[] = { |
{0xf3ff0000, 0x41000000}, /* BCzF */ |
{0xf3ff0000, 0x41020000}, /* BCzFL */ |
{0xf3ff0000, 0x41010000}, /* BCzT */ |
117,7 → 120,7 |
{0xfc000000, 0x08000000}, /* J */ |
{0xfc000000, 0x0c000000}, /* JAL */ |
{0xfc1f07ff, 0x00000009}, /* JALR */ |
{0,0} /* EndOfTable */ |
{0, 0} /* EndOfTable */ |
}; |
/** Test, if the given instruction is a jump or branch instruction |
129,7 → 132,7 |
{ |
int i; |
for (i=0;jmpinstr[i].andmask;i++) { |
for (i = 0; jmpinstr[i].andmask; i++) { |
if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value) |
return true; |
} |
157,9 → 160,11 |
printf("Duplicate breakpoint %d.\n", i); |
spinlock_unlock(&bkpoints_lock); |
return 0; |
} else if (breakpoints[i].address == (uintptr_t)argv->intval + sizeof(unative_t) || \ |
breakpoints[i].address == (uintptr_t)argv->intval - sizeof(unative_t)) { |
printf("Adjacent breakpoints not supported, conflict with %d.\n", i); |
} else if (breakpoints[i].address == (uintptr_t)argv->intval + |
sizeof(unative_t) || breakpoints[i].address == |
(uintptr_t)argv->intval - sizeof(unative_t)) { |
printf("Adjacent breakpoints not supported, conflict " |
"with %d.\n", i); |
spinlock_unlock(&bkpoints_lock); |
return 0; |
} |
166,7 → 171,7 |
} |
for (i=0; i<BKPOINTS_MAX; i++) |
for (i = 0; i < BKPOINTS_MAX; i++) |
if (!breakpoints[i].address) { |
cur = &breakpoints[i]; |
break; |
185,7 → 190,7 |
cur->flags = 0; |
} else { /* We are add extended */ |
cur->flags = BKPOINT_FUNCCALL; |
cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval; |
cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval; |
} |
if (is_jump(cur->instruction)) |
cur->flags |= BKPOINT_ONESHOT; |
193,6 → 198,7 |
/* Set breakpoint */ |
*((unative_t *)cur->address) = 0x0d; |
smc_coherence(cur->address); |
spinlock_unlock(&bkpoint_lock); |
interrupts_restore(ipl); |
200,8 → 206,6 |
return 1; |
} |
/** Remove breakpoint from table */ |
int cmd_del_breakpoint(cmd_arg_t *argv) |
{ |
229,7 → 233,9 |
return 0; |
} |
((uint32_t *)cur->address)[0] = cur->instruction; |
smc_coherence(((uint32_t *)cur->address)[0]); |
((uint32_t *)cur->address)[1] = cur->nextinstruction; |
smc_coherence(((uint32_t *)cur->address)[1]); |
cur->address = NULL; |
252,11 → 258,11 |
symbol = get_symtab_entry(breakpoints[i].address); |
printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" : "false"), |
((breakpoints[i].flags & BKPOINT_ONESHOT) ? "true" : "false"), |
((breakpoints[i].flags & BKPOINT_FUNCCALL) ? "true" : "false"), |
symbol); |
breakpoints[i].counter, breakpoints[i].address, |
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" : |
"false"), ((breakpoints[i].flags & BKPOINT_ONESHOT) |
? "true" : "false"), ((breakpoints[i].flags & |
BKPOINT_FUNCCALL) ? "true" : "false"), symbol); |
} |
return 1; |
} |
266,7 → 272,7 |
{ |
int i; |
for (i=0; i<BKPOINTS_MAX; i++) |
for (i = 0; i < BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
cmd_initialize(&bkpts_info); |
305,16 → 311,16 |
panic("Breakpoint in branch delay slot not supported.\n"); |
spinlock_lock(&bkpoint_lock); |
for (i=0; i<BKPOINTS_MAX; i++) { |
for (i = 0; i < BKPOINTS_MAX; i++) { |
/* Normal breakpoint */ |
if (fireaddr == breakpoints[i].address \ |
&& !(breakpoints[i].flags & BKPOINT_REINST)) { |
if (fireaddr == breakpoints[i].address && |
!(breakpoints[i].flags & BKPOINT_REINST)) { |
cur = &breakpoints[i]; |
break; |
} |
/* Reinst only breakpoint */ |
if ((breakpoints[i].flags & BKPOINT_REINST) \ |
&& (fireaddr == breakpoints[i].address + sizeof(unative_t))) { |
if ((breakpoints[i].flags & BKPOINT_REINST) && |
(fireaddr == breakpoints[i].address + sizeof(unative_t))) { |
cur = &breakpoints[i]; |
break; |
} |
323,8 → 329,10 |
if (cur->flags & BKPOINT_REINST) { |
/* Set breakpoint on first instruction */ |
((uint32_t *)cur->address)[0] = 0x0d; |
smc_coherence(((uint32_t *)cur->address)[0]); |
/* Return back the second */ |
((uint32_t *)cur->address)[1] = cur->nextinstruction; |
smc_coherence(((uint32_t *)cur->address)[1]); |
cur->flags &= ~BKPOINT_REINST; |
spinlock_unlock(&bkpoint_lock); |
return; |
333,11 → 341,12 |
printf("Warning: breakpoint recursion\n"); |
if (!(cur->flags & BKPOINT_FUNCCALL)) |
printf("***Breakpoint %d: %p in %s.\n", i, |
fireaddr, get_symtab_entry(istate->epc)); |
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr, |
get_symtab_entry(istate->epc)); |
/* Return first instruction back */ |
((uint32_t *)cur->address)[0] = cur->instruction; |
smc_coherence(cur->address); |
if (! (cur->flags & BKPOINT_ONESHOT)) { |
/* Set Breakpoint on next instruction */ |
/branches/dynload/kernel/arch/ia32/include/types.h |
---|
57,30 → 57,28 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "x" |
#define PRIs "u" |
#define PRIc "u" |
#define PRIi "u" |
#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. */ |
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */ |
#define PRId8 "d" |
#define PRId16 "d" |
#define PRId32 "d" |
#define PRId64 "lld" |
#define PRIdn "d" |
#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" |
#define PRIu16 "u" |
#define PRIu32 "u" |
#define PRIu64 "llu" |
#define PRIun "u" |
#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" |
#define PRIx16 "x" |
#define PRIx32 "x" |
#define PRIx64 "llx" |
#define PRIxn "x" |
#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 { |
/branches/dynload/kernel/arch/ia32/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
#endif |
/branches/dynload/kernel/arch/ia32/include/barrier.h |
---|
95,6 → 95,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/dynload/kernel/arch/ia32/src/pm.c |
---|
112,7 → 112,7 |
void tss_initialize(tss_t *t) |
{ |
memsetb((uintptr_t) t, sizeof(struct tss), 0); |
memsetb(t, sizeof(struct tss), 0); |
} |
/* |
240,7 → 240,7 |
preemption_disable(); |
ipl_t ipl = interrupts_disable(); |
memsetb((uintptr_t) idt, sizeof(idt), 0); |
memsetb(idt, sizeof(idt), 0); |
ptr_16_32_t idtr; |
idtr.limit = sizeof(idt); |
/branches/dynload/kernel/arch/ia32/src/smp/smp.c |
---|
160,8 → 160,7 |
panic("couldn't allocate memory for GDT\n"); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb((uintptr_t)(&gdt_new[TSS_DES]), |
sizeof(struct descriptor), 0); |
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor); |
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); |
gdtr.base = (uintptr_t) gdt_new; |
/branches/dynload/kernel/arch/ia32/src/smp/ap.S |
---|
45,7 → 45,7 |
KTEXT=8 |
KDATA=16 |
# This piece of code is real-mode and is meant to be alligned at 4K boundary. |
# This piece of code is real-mode and is meant to be aligned at 4K boundary. |
# The requirement for such an alignment comes from MP Specification's STARTUP IPI |
# requirements. |
/branches/dynload/kernel/arch/ia32/src/drivers/ega.c |
---|
115,7 → 115,7 |
return; |
memcpy((void *) videoram, (void *) (videoram + ROW * 2), (SCREEN - ROW) * 2); |
memsetw((uintptr_t) (videoram + (SCREEN - ROW) * 2), ROW, 0x0720); |
memsetw(videoram + (SCREEN - ROW) * 2, ROW, 0x0720); |
ega_cursor = ega_cursor - ROW; |
} |
/branches/dynload/uspace/app/init/init.c |
---|
131,7 → 131,7 |
spawn("/sbin/tetris"); |
spawn("/sbin/cli"); |
// FIXME: spawn("/sbin/tester"); |
// FIXME: spawn("/sbin/klog"); |
spawn("/sbin/klog"); |
free(buf); |
return 0; |
/branches/dynload/uspace/app/tester/tester.c |
---|
128,10 → 128,15 |
printf("Unknown test\n\n"); |
else |
run_test(test); |
} else if (c == '*') |
} else if (c == '*') { |
run_safe_tests(); |
else |
} else if (c < 0) { |
/* got EOF */ |
break; |
} else { |
printf("Invalid test\n\n"); |
} |
} |
} |
/branches/dynload/uspace/app/klog/klog.c |
---|
40,46 → 40,62 |
#include <ipc/services.h> |
#include <as.h> |
#include <sysinfo.h> |
#include <io/stream.h> |
#include <errno.h> |
#define NAME "klog" |
#define KLOG_SIZE PAGE_SIZE |
/* Pointer to klog area */ |
static char *klog; |
static void console_wait(void) |
{ |
while (get_cons_phone() < 0) |
usleep(50000); // FIXME |
} |
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
int i; |
async_serialize_start(); |
async_serialize_start(); |
for (i=0; klog[i + IPC_GET_ARG1(*call)] && i < IPC_GET_ARG2(*call); i++) |
putchar(klog[i + IPC_GET_ARG1(*call)]); |
putchar('\n'); |
size_t klog_start = (size_t) IPC_GET_ARG1(*call); |
size_t klog_len = (size_t) IPC_GET_ARG2(*call); |
size_t klog_stored = (size_t) IPC_GET_ARG3(*call); |
size_t i; |
for (i = klog_len - klog_stored; i < klog_len; i++) |
putchar(klog[(klog_start + i) % KLOG_SIZE]); |
async_serialize_end(); |
} |
int main(int argc, char *argv[]) |
{ |
int res; |
void *mapping; |
printf("Kernel console output.\n"); |
console_wait(); |
mapping = as_get_mappable_page(PAGE_SIZE); |
res = ipc_share_in_start_1_0(PHONE_NS, mapping, PAGE_SIZE, |
klog = (char *) as_get_mappable_page(KLOG_SIZE); |
if (klog == NULL) { |
printf(NAME ": Error allocating memory area\n"); |
return -1; |
} |
int res = ipc_share_in_start_1_0(PHONE_NS, (void *) klog, KLOG_SIZE, |
SERVICE_MEM_KLOG); |
if (res) { |
printf("Failed to initialize klog memarea\n"); |
_exit(1); |
if (res != EOK) { |
printf(NAME ": Error initializing memory area\n"); |
return -1; |
} |
klog = mapping; |
int inr = sysinfo_value("klog.inr"); |
int devno = sysinfo_value("klog.devno"); |
if (ipc_register_irq(inr, devno, 0, NULL)) { |
printf("Error registering for klog service.\n"); |
return 0; |
if (ipc_register_irq(inr, devno, 0, NULL) != EOK) { |
printf(NAME ": Error registering klog notifications\n"); |
return -1; |
} |
async_set_interrupt_received(interrupt_received); |
klog_update(); |
async_manager(); |
return 0; |
/branches/dynload/uspace/lib/libc/include/stdio.h |
---|
49,7 → 49,7 |
int n; \ |
n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \ |
if (n > 0) \ |
(void) __SYSCALL3(SYS_IO, 1, (sysarg_t) buf, strlen(buf)); \ |
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, strlen(buf)); \ |
} |
extern int getchar(void); |
/branches/dynload/uspace/lib/libc/include/io/stream.h |
---|
40,6 → 40,7 |
#define EMFILE -17 |
extern void open_console(void); |
extern void klog_update(void); |
extern ssize_t read_stdin(void *, size_t); |
extern ssize_t write_stdout(const void *, size_t); |
/branches/dynload/uspace/lib/libc/generic/io/stream.c |
---|
67,6 → 67,8 |
((char *) buf)[i++] = r0; |
} |
return i; |
} else { |
return -1; |
} |
} |
82,7 → 84,7 |
return count; |
} else |
return __SYSCALL3(SYS_IO, 1, (sysarg_t) buf, count); |
return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, count); |
} |
void open_console(void) |
94,6 → 96,11 |
} |
} |
void klog_update(void) |
{ |
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0); |
} |
int get_cons_phone(void) |
{ |
open_console(); |
/branches/dynload/uspace/lib/libc/arch/ia64/src/entry.s |
---|
31,7 → 31,6 |
.org 0 |
.globl __entry |
.globl __entry_driver |
## User-space task entry point |
# |
41,17 → 40,6 |
mov r1 = _gp |
br.call.sptk.many b0 = __main |
0: |
br.call.sptk.many b0 = __io_init |
1: |
br.call.sptk.many b0 = main |
2: |
br.call.sptk.many b0 = __exit |
__entry_driver: |
alloc loc0 = ar.pfs, 0, 1, 2, 0 |
mov r1 = _gp |
br.call.sptk.many b0 = __main |
0: |
br.call.sptk.many b0 = main |
1: |
br.call.sptk.many b0 = __exit |
/branches/dynload/uspace/lib/libc/arch/arm32/src/entry.s |
---|
31,7 → 31,6 |
.org 0 |
.global __entry |
.global __entry_driver |
## User-space task entry point |
# |
38,12 → 37,5 |
# |
__entry: |
bl __main |
bl __io_init |
bl main |
bl __exit |
__entry_driver: |
bl __main |
bl main |
bl __exit |
/branches/dynload/uspace/lib/libc/arch/mips32/src/entry.s |
---|
52,9 → 52,6 |
jal __main |
nop |
jal __io_init |
nop |
jal main |
nop |
62,28 → 59,6 |
nop |
.end |
.ent __entry_driver |
__entry_driver: |
.frame $sp, 32, $31 |
.cpload $25 |
# Mips o32 may store its arguments on stack, make space (16 bytes), |
# so that it could work with -O0 |
# Make space additional 16 bytes for the stack frame |
addiu $sp, -32 |
.cprestore 16 # Allow PIC code |
jal __main |
nop |
jal main |
nop |
jal __exit |
nop |
.end |
# Alignment of output section data to 0x4000 |
.section .data |
.align 14 |
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs.h |
---|
40,7 → 40,9 |
#include <bool.h> |
#include <libadt/hash_table.h> |
#ifndef dprintf |
#define dprintf(...) printf(__VA_ARGS__) |
#endif |
typedef struct tmpfs_dentry { |
fs_index_t index; /**< TMPFS node index. */ |
60,6 → 62,9 |
extern fs_reg_t tmpfs_reg; |
extern libfs_ops_t tmpfs_libfs_ops; |
extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_mount(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_read(ipc_callid_t, ipc_call_t *); |
67,6 → 72,8 |
extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *); |
extern bool tmpfs_restore(dev_handle_t); |
#endif |
/** |
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs_dump.c |
---|
0,0 → 1,253 |
/* |
* Copyright (c) 2008 Jakub Jermar |
* Copyright (c) 2008 Martin Decky |
* 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 fs |
* @{ |
*/ |
/** |
* @file tmpfs_dump.c |
* @brief Support for loading TMPFS file system dump. |
*/ |
#include "tmpfs.h" |
#include "../../vfs/vfs.h" |
#include <ipc/ipc.h> |
#include <errno.h> |
#include <stdlib.h> |
#include <string.h> |
#include <sys/types.h> |
#include <as.h> |
#include <libfs.h> |
#include <ipc/services.h> |
#include <ipc/devmap.h> |
#include <sys/mman.h> |
#include <byteorder.h> |
#define BLOCK_SIZE 1024 // FIXME |
#define RD_BASE 1024 // FIXME |
#define RD_READ_BLOCK (RD_BASE + 1) |
struct rdentry { |
uint8_t type; |
uint32_t len; |
} __attribute__((packed)); |
static bool |
tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen, |
size_t *pos, void *dst, size_t size) |
{ |
size_t offset = 0; |
size_t left = size; |
while (left > 0) { |
size_t rd; |
if (*bufpos + left < *buflen) |
rd = left; |
else |
rd = *buflen - *bufpos; |
if (rd > 0) { |
memcpy(dst + offset, buffer + *bufpos, rd); |
offset += rd; |
*bufpos += rd; |
*pos += rd; |
left -= rd; |
} |
if (*bufpos == *buflen) { |
ipcarg_t retval; |
int rc = ipc_call_sync_2_1(phone, RD_READ_BLOCK, |
*pos / BLOCK_SIZE, BLOCK_SIZE, |
&retval); |
if ((rc != EOK) || (retval != EOK)) |
return false; |
*bufpos = 0; |
*buflen = BLOCK_SIZE; |
} |
} |
return true; |
} |
static bool |
tmpfs_restore_recursion(int phone, void *block, size_t *bufpos, size_t *buflen, |
size_t *pos, tmpfs_dentry_t *parent) |
{ |
struct rdentry entry; |
libfs_ops_t *ops = &tmpfs_libfs_ops; |
do { |
char *fname; |
tmpfs_dentry_t *node; |
uint32_t size; |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &entry, |
sizeof(entry))) |
return false; |
entry.len = uint32_t_le2host(entry.len); |
switch (entry.type) { |
case 0: |
break; |
case 1: |
fname = malloc(entry.len + 1); |
if (fname == NULL) |
return false; |
node = (tmpfs_dentry_t *) ops->create(L_FILE); |
if (node == NULL) { |
free(fname); |
return false; |
} |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, |
fname, entry.len)) { |
ops->destroy((void *) node); |
free(fname); |
return false; |
} |
fname[entry.len] = 0; |
if (!ops->link((void *) parent, (void *) node, fname)) { |
ops->destroy((void *) node); |
free(fname); |
return false; |
} |
free(fname); |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, |
&size, sizeof(size))) |
return false; |
size = uint32_t_le2host(size); |
node->data = malloc(size); |
if (node->data == NULL) |
return false; |
node->size = size; |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, |
node->data, size)) |
return false; |
break; |
case 2: |
fname = malloc(entry.len + 1); |
if (fname == NULL) |
return false; |
node = (tmpfs_dentry_t *) ops->create(L_DIRECTORY); |
if (node == NULL) { |
free(fname); |
return false; |
} |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, |
fname, entry.len)) { |
ops->destroy((void *) node); |
free(fname); |
return false; |
} |
fname[entry.len] = 0; |
if (!ops->link((void *) parent, (void *) node, fname)) { |
ops->destroy((void *) node); |
free(fname); |
return false; |
} |
free(fname); |
if (!tmpfs_restore_recursion(phone, block, bufpos, |
buflen, pos, node)) |
return false; |
break; |
default: |
return false; |
} |
} while (entry.type != 0); |
return true; |
} |
bool tmpfs_restore(dev_handle_t dev) |
{ |
libfs_ops_t *ops = &tmpfs_libfs_ops; |
void *block = mmap(NULL, BLOCK_SIZE, |
PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
if (block == NULL) |
return false; |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
DEVMAP_CONNECT_TO_DEVICE, dev); |
if (phone < 0) { |
munmap(block, BLOCK_SIZE); |
return false; |
} |
if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) != |
EOK) |
goto error; |
size_t bufpos = 0; |
size_t buflen = 0; |
size_t pos = 0; |
char tag[6]; |
if (!tmpfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5)) |
goto error; |
tag[5] = 0; |
if (strcmp(tag, "TMPFS") != 0) |
goto error; |
if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos, |
ops->root_get(dev))) |
goto error; |
ipc_hangup(phone); |
munmap(block, BLOCK_SIZE); |
return true; |
error: |
ipc_hangup(phone); |
munmap(block, BLOCK_SIZE); |
return false; |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs.c |
---|
61,6 → 61,7 |
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_MOUNTED)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_DESTROY)] = VFS_OP_DEFINED, |
} |
105,6 → 106,9 |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case VFS_MOUNTED: |
tmpfs_mounted(callid, &call); |
break; |
case VFS_MOUNT: |
tmpfs_mount(callid, &call); |
break; |
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs_ops.c |
---|
50,10 → 50,6 |
#include <libadt/hash_table.h> |
#include <as.h> |
#include <libfs.h> |
#include <ipc/services.h> |
#include <ipc/devmap.h> |
#include <sys/mman.h> |
#include <byteorder.h> |
#define min(a, b) ((a) < (b) ? (a) : (b)) |
#define max(a, b) ((a) > (b) ? (a) : (b)) |
62,10 → 58,6 |
#define NAMES_BUCKETS 4 |
#define BLOCK_SIZE 1024 // FIXME |
#define RD_BASE 1024 // FIXME |
#define RD_READ_BLOCK (RD_BASE + 1) |
/* |
* For now, we don't distinguish between different dev_handles/instances. All |
* requests resolve to the only instance, rooted in the following variable. |
148,11 → 140,6 |
/** Hash table of all directory entries. */ |
hash_table_t dentries; |
struct rdentry { |
uint8_t type; |
uint32_t len; |
} __attribute__((packed)); |
/* Implementation of hash table interface for the dentries hash table. */ |
static hash_index_t dentries_hash(unsigned long *key) |
{ |
250,177 → 237,6 |
return true; |
} |
static bool tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen, size_t *pos, void *dst, size_t size) |
{ |
size_t offset = 0; |
size_t left = size; |
while (left > 0) { |
size_t rd; |
if (*bufpos + left < *buflen) |
rd = left; |
else |
rd = *buflen - *bufpos; |
if (rd > 0) { |
memcpy(dst + offset, buffer + *bufpos, rd); |
offset += rd; |
*bufpos += rd; |
*pos += rd; |
left -= rd; |
} |
if (*bufpos == *buflen) { |
int retval; |
int rc = ipc_call_sync_2_1(phone, RD_READ_BLOCK, *pos / BLOCK_SIZE, BLOCK_SIZE, (sysarg_t *) &retval); |
if ((rc != EOK) || (retval != EOK)) |
return false; |
*bufpos = 0; |
*buflen = BLOCK_SIZE; |
} |
} |
return true; |
} |
static bool tmpfs_restore_recursion(int phone, void *block, size_t *bufpos, size_t *buflen, size_t *pos, tmpfs_dentry_t *parent) |
{ |
struct rdentry entry; |
do { |
char *fname; |
tmpfs_dentry_t *node; |
uint32_t size; |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &entry, sizeof(entry))) |
return false; |
entry.len = uint32_t_le2host(entry.len); |
switch (entry.type) { |
case 0: |
break; |
case 1: |
fname = malloc(entry.len + 1); |
if (fname == NULL) |
return false; |
node = (tmpfs_dentry_t *) tmpfs_create_node(L_FILE); |
if (node == NULL) { |
free(fname); |
return false; |
} |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, fname, entry.len)) { |
tmpfs_destroy_node((void *) node); |
free(fname); |
return false; |
} |
fname[entry.len] = 0; |
if (!tmpfs_link_node((void *) parent, (void *) node, fname)) { |
tmpfs_destroy_node((void *) node); |
free(fname); |
return false; |
} |
free(fname); |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &size, sizeof(size))) |
return false; |
size = uint32_t_le2host(size); |
node->data = malloc(size); |
if (node->data == NULL) |
return false; |
node->size = size; |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, node->data, size)) |
return false; |
break; |
case 2: |
fname = malloc(entry.len + 1); |
if (fname == NULL) |
return false; |
node = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY); |
if (node == NULL) { |
free(fname); |
return false; |
} |
if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, fname, entry.len)) { |
tmpfs_destroy_node((void *) node); |
free(fname); |
return false; |
} |
fname[entry.len] = 0; |
if (!tmpfs_link_node((void *) parent, (void *) node, fname)) { |
tmpfs_destroy_node((void *) node); |
free(fname); |
return false; |
} |
free(fname); |
if (!tmpfs_restore_recursion(phone, block, bufpos, buflen, pos, node)) |
return false; |
break; |
default: |
return false; |
} |
} while (entry.type != 0); |
return true; |
} |
static bool tmpfs_restore(dev_handle_t dev) |
{ |
void *block = mmap(NULL, BLOCK_SIZE, |
PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
if (block == NULL) |
return false; |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, dev); |
if (phone < 0) { |
munmap(block, BLOCK_SIZE); |
return false; |
} |
if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) != EOK) |
goto error; |
size_t bufpos = 0; |
size_t buflen = 0; |
size_t pos = 0; |
char tag[6]; |
if (!tmpfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5)) |
goto error; |
tag[5] = 0; |
if (strcmp(tag, "TMPFS") != 0) |
goto error; |
if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos, root)) |
goto error; |
ipc_hangup(phone); |
munmap(block, BLOCK_SIZE); |
return true; |
error: |
ipc_hangup(phone); |
munmap(block, BLOCK_SIZE); |
return false; |
} |
/** Compare one component of path to a directory entry. |
* |
* @param parentp Pointer to node from which we descended. |
577,36 → 393,38 |
return EOK; |
} |
void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
/* Initialize TMPFS. */ |
if (!root && !tmpfs_init()) { |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
if (dev_handle >= 0) { |
if (tmpfs_restore(dev_handle)) |
ipc_answer_0(rid, EOK); |
else |
ipc_answer_0(rid, ELIMIT); |
} else { |
ipc_answer_0(rid, EOK); |
} |
} |
void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
fs_index_t mr_index = (fs_index_t) IPC_GET_ARG2(*request); |
fs_handle_t mp_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request); |
dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request); |
fs_index_t mp_index = (fs_index_t) IPC_GET_ARG5(*request); |
dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
fs_index_t mp_index = (fs_index_t) IPC_GET_ARG2(*request); |
fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request); |
dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request); |
if ((mr_index == root->index) && |
(mp_fs_handle == tmpfs_reg.fs_handle) && |
(mp_index == mr_index)) { |
if (mr_dev_handle >= 0) { |
if (tmpfs_restore(mr_dev_handle)) |
ipc_answer_0(rid, EOK); |
else |
ipc_answer_0(rid, ELIMIT); |
} else |
ipc_answer_0(rid, EOK); |
} else |
ipc_answer_0(rid, ENOTSUP); |
ipc_answer_0(rid, ENOTSUP); |
} |
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) |
{ |
/* Initialize TMPFS. */ |
if (!root && !tmpfs_init()) { |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); |
} |
/branches/dynload/uspace/srv/fs/tmpfs/Makefile |
---|
44,7 → 44,8 |
OUTPUT = tmpfs |
SOURCES = \ |
tmpfs.c \ |
tmpfs_ops.c |
tmpfs_ops.c \ |
tmpfs_dump.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
/branches/dynload/uspace/srv/fs/fat/fat_idx.c |
---|
74,6 → 74,32 |
/** List of unused structures. */ |
static LIST_INITIALIZE(unused_head); |
static void unused_initialize(unused_t *u, dev_handle_t dev_handle) |
{ |
link_initialize(&u->link); |
u->dev_handle = dev_handle; |
u->next = 0; |
u->remaining = ((uint64_t)((fs_index_t)-1)) + 1; |
list_initialize(&u->freed_head); |
} |
static unused_t *unused_find(dev_handle_t dev_handle, bool lock) |
{ |
unused_t *u; |
link_t *l; |
if (lock) |
futex_down(&unused_futex); |
for (l = unused_head.next; l != &unused_head; l = l->next) { |
u = list_get_instance(l, unused_t, link); |
if (u->dev_handle == dev_handle) |
return u; |
} |
if (lock) |
futex_up(&unused_futex); |
return NULL; |
} |
/** Futex protecting the up_hash and ui_hash. */ |
static futex_t used_futex = FUTEX_INITIALIZER; |
190,22 → 216,13 |
/** Allocate a VFS index which is not currently in use. */ |
static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index) |
{ |
link_t *l; |
unused_t *u; |
assert(index); |
futex_down(&unused_futex); |
for (l = unused_head.next; l != &unused_head; l = l->next) { |
u = list_get_instance(l, unused_t, link); |
if (u->dev_handle == dev_handle) |
goto hit; |
} |
futex_up(&unused_futex); |
/* dev_handle not found */ |
return false; |
u = unused_find(dev_handle, true); |
if (!u) |
return false; |
hit: |
if (list_empty(&u->freed_head)) { |
if (u->remaining) { |
/* |
261,21 → 278,11 |
/** Free a VFS index, which is no longer in use. */ |
static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index) |
{ |
link_t *l; |
unused_t *u; |
futex_down(&unused_futex); |
for (l = unused_head.next; l != &unused_head; l = l->next) { |
u = list_get_instance(l, unused_t, link); |
if (u->dev_handle == dev_handle) |
goto hit; |
} |
futex_up(&unused_futex); |
u = unused_find(dev_handle, true); |
assert(u); |
/* should not happen */ |
assert(0); |
hit: |
if (u->next == index + 1) { |
/* The index can be returned directly to the counter. */ |
u->next--; |
401,3 → 408,60 |
return fidx; |
} |
int fat_idx_init(void) |
{ |
if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops)) |
return ENOMEM; |
if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) { |
hash_table_destroy(&up_hash); |
return ENOMEM; |
} |
return EOK; |
} |
void fat_idx_fini(void) |
{ |
/* We assume the hash tables are empty. */ |
hash_table_destroy(&up_hash); |
hash_table_destroy(&ui_hash); |
} |
int fat_idx_init_by_dev_handle(dev_handle_t dev_handle) |
{ |
unused_t *u; |
int rc = EOK; |
u = (unused_t *) malloc(sizeof(unused_t)); |
if (!u) |
return ENOMEM; |
unused_initialize(u, dev_handle); |
futex_down(&unused_futex); |
if (!unused_find(dev_handle, false)) |
list_append(&u->link, &unused_head); |
else |
rc = EEXIST; |
futex_up(&unused_futex); |
return rc; |
} |
void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle) |
{ |
unused_t *u; |
u = unused_find(dev_handle, true); |
assert(u); |
list_remove(&u->link); |
futex_up(&unused_futex); |
while (!list_empty(&u->freed_head)) { |
freed_t *f; |
f = list_get_instance(u->freed_head.next, freed_t, link); |
list_remove(&f->link); |
free(f); |
} |
free(u); |
} |
/** |
* @} |
*/ |
/branches/dynload/uspace/srv/fs/fat/fat.h |
---|
40,7 → 40,9 |
#include <bool.h> |
#include "../../vfs/vfs.h" |
#ifndef dprintf |
#define dprintf(...) printf(__VA_ARGS__) |
#endif |
typedef struct { |
uint8_t ji[3]; /**< Jump instruction. */ |
217,11 → 219,18 |
extern fs_reg_t fat_reg; |
extern void fat_mounted(ipc_callid_t, ipc_call_t *); |
extern void fat_mount(ipc_callid_t, ipc_call_t *); |
extern void fat_lookup(ipc_callid_t, ipc_call_t *); |
extern fat_idx_t *fat_idx_get_by_pos(dev_handle_t, fat_cluster_t, unsigned); |
extern fat_idx_t *fat_idx_get_by_index(dev_handle_t, fs_index_t); |
extern int fat_idx_init(void); |
extern void fat_idx_fini(void); |
extern int fat_idx_init_by_dev_handle(dev_handle_t); |
extern void fat_idx_fini_by_dev_handle(dev_handle_t); |
#endif |
/** |
/branches/dynload/uspace/srv/fs/fat/fat.c |
---|
55,6 → 55,7 |
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_MOUNTED)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL, |
} |
}; |
97,6 → 98,12 |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case VFS_MOUNTED: |
fat_mounted(callid, &call); |
break; |
case VFS_MOUNT: |
fat_mount(callid, &call); |
break; |
case VFS_LOOKUP: |
fat_lookup(callid, &call); |
break; |
110,9 → 117,14 |
int main(int argc, char **argv) |
{ |
int vfs_phone; |
int rc; |
printf("FAT: HelenOS FAT file system server.\n"); |
rc = fat_idx_init(); |
if (rc != EOK) |
goto err; |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
while (vfs_phone < EOK) { |
usleep(10000); |
119,11 → 131,10 |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
} |
int rc; |
rc = fs_register(vfs_phone, &fat_reg, &fat_vfs_info, fat_connection); |
if (rc != EOK) { |
printf("Failed to register the FAT file system (%d)\n", rc); |
return rc; |
fat_idx_fini(); |
goto err; |
} |
dprintf("FAT filesystem registered, fs_handle=%d.\n", |
132,6 → 143,10 |
async_manager(); |
/* not reached */ |
return 0; |
err: |
printf("Failed to register the FAT file system (%d)\n", rc); |
return rc; |
} |
/** |
/branches/dynload/uspace/srv/fs/fat/fat_ops.c |
---|
112,12 → 112,17 |
#define FAT_BS(b) ((fat_bs_t *)((b)->data)) |
#define FAT_CLST_RES0 0x0000 |
#define FAT_CLST_RES1 0x0001 /* internally used to mark root directory */ |
#define FAT_CLST_RES1 0x0001 |
#define FAT_CLST_FIRST 0x0002 |
#define FAT_CLST_BAD 0xfff7 |
#define FAT_CLST_LAST1 0xfff8 |
#define FAT_CLST_LAST8 0xffff |
/* internally used to mark root directory's parent */ |
#define FAT_CLST_ROOTPAR FAT_CLST_RES0 |
/* internally used to mark root directory */ |
#define FAT_CLST_ROOT FAT_CLST_RES1 |
#define fat_block_get(np, off) \ |
_fat_block_get((np)->idx->dev_handle, (np)->firstc, (off)) |
151,7 → 156,7 |
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
ssa = rscnt + fatcnt * sf + rds; |
if (firstc == FAT_CLST_RES1) { |
if (firstc == FAT_CLST_ROOT) { |
/* root directory special case */ |
assert(offset < rds); |
b = block_get(dev_handle, rscnt + fatcnt * sf + offset); |
521,7 → 526,7 |
static void *fat_root_get(dev_handle_t dev_handle) |
{ |
return NULL; /* TODO */ |
return fat_node_get(dev_handle, 0); |
} |
static char fat_plb_get_char(unsigned pos) |
558,6 → 563,60 |
.is_file = fat_is_file |
}; |
void fat_mounted(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
block_t *bb; |
uint16_t rde; |
int rc; |
/* Read the number of root directory entries. */ |
bb = block_get(dev_handle, BS_BLOCK); |
rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max); |
block_put(bb); |
rc = fat_idx_init_by_dev_handle(dev_handle); |
if (rc != EOK) { |
ipc_answer_0(rid, rc); |
return; |
} |
/* Initialize the root node. */ |
fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t)); |
if (!rootp) { |
fat_idx_fini_by_dev_handle(dev_handle); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
fat_node_initialize(rootp); |
fat_idx_t *ridxp = fat_idx_get_by_pos(dev_handle, FAT_CLST_ROOTPAR, 0); |
if (!ridxp) { |
free(rootp); |
fat_idx_fini_by_dev_handle(dev_handle); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
assert(ridxp->index == 0); |
/* ridxp->lock held */ |
rootp->type = FAT_DIRECTORY; |
rootp->firstc = FAT_CLST_ROOT; |
rootp->refcnt = 1; |
rootp->size = rde * sizeof(fat_dentry_t); |
rootp->idx = ridxp; |
ridxp->nodep = rootp; |
futex_up(&ridxp->lock); |
ipc_answer_0(rid, EOK); |
} |
void fat_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
ipc_answer_0(rid, ENOTSUP); |
} |
void fat_lookup(ipc_callid_t rid, ipc_call_t *request) |
{ |
libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request); |
/branches/dynload/uspace/srv/vfs/vfs_ops.c |
---|
62,24 → 62,11 |
RWLOCK_INITIALIZE(namespace_rwlock); |
futex_t rootfs_futex = FUTEX_INITIALIZER; |
vfs_triplet_t rootfs = { |
vfs_pair_t rootfs = { |
.fs_handle = 0, |
.dev_handle = 0, |
.index = 0, |
.dev_handle = 0 |
}; |
static int |
lookup_root(fs_handle_t fs_handle, dev_handle_t dev_handle, |
vfs_lookup_res_t *result) |
{ |
vfs_pair_t altroot = { |
.fs_handle = fs_handle, |
.dev_handle = dev_handle, |
}; |
return vfs_lookup_internal("/", L_DIRECTORY, result, &altroot); |
} |
void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle; |
163,27 → 150,7 |
(void) ipc_data_write_finalize(callid, buf, size); |
buf[size] = '\0'; |
/* |
* Lookup the root node of the filesystem being mounted. |
* In this case, we don't need to take the namespace_futex as the root |
* node cannot be removed. However, we do take a reference to it so |
* that we can track how many times it has been mounted. |
*/ |
vfs_lookup_res_t mr_res; |
rc = lookup_root(fs_handle, dev_handle, &mr_res); |
if (rc != EOK) { |
free(buf); |
ipc_answer_0(rid, rc); |
return; |
} |
vfs_node_t *mr_node = vfs_node_get(&mr_res); |
if (!mr_node) { |
free(buf); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
/* Finally, we need to resolve the path to the mountpoint. */ |
/* Resolve the path to the mountpoint. */ |
vfs_lookup_res_t mp_res; |
futex_down(&rootfs_futex); |
if (rootfs.fs_handle) { |
193,7 → 160,6 |
/* Trying to mount root FS over root FS */ |
rwlock_write_unlock(&namespace_rwlock); |
futex_up(&rootfs_futex); |
vfs_node_put(mr_node); |
free(buf); |
ipc_answer_0(rid, EBUSY); |
return; |
203,7 → 169,6 |
/* The lookup failed for some reason. */ |
rwlock_write_unlock(&namespace_rwlock); |
futex_up(&rootfs_futex); |
vfs_node_put(mr_node); /* failed -> drop reference */ |
free(buf); |
ipc_answer_0(rid, rc); |
return; |
212,7 → 177,6 |
if (!mp_node) { |
rwlock_write_unlock(&namespace_rwlock); |
futex_up(&rootfs_futex); |
vfs_node_put(mr_node); /* failed -> drop reference */ |
free(buf); |
ipc_answer_0(rid, ENOMEM); |
return; |
232,20 → 196,16 |
*/ |
free(buf); |
/* Inform the mount point about the root mount. */ |
phone = vfs_grab_phone(mr_res.triplet.fs_handle); |
rc = async_req_5_0(phone, VFS_MOUNT, |
(ipcarg_t) mr_res.triplet.dev_handle, |
(ipcarg_t) mr_res.triplet.index, |
(ipcarg_t) mr_res.triplet.fs_handle, |
(ipcarg_t) mr_res.triplet.dev_handle, |
(ipcarg_t) mr_res.triplet.index); |
/* Tell the mountee that it is being mounted. */ |
phone = vfs_grab_phone(fs_handle); |
rc = async_req_1_0(phone, VFS_MOUNTED, |
(ipcarg_t) dev_handle); |
vfs_release_phone(phone); |
if (rc == EOK) |
rootfs = mr_res.triplet; |
else |
vfs_node_put(mr_node); |
if (rc == EOK) { |
rootfs.fs_handle = fs_handle; |
rootfs.dev_handle = dev_handle; |
} |
futex_up(&rootfs_futex); |
ipc_answer_0(rid, rc); |
257,7 → 217,6 |
*/ |
futex_up(&rootfs_futex); |
free(buf); |
vfs_node_put(mr_node); /* failed -> drop reference */ |
ipc_answer_0(rid, ENOENT); |
return; |
} |
268,26 → 227,19 |
/* |
* At this point, we have all necessary pieces: file system and device |
* handles, and we know the mount point VFS node and also the root node |
* of the file system being mounted. |
* handles, and we know the mount point VFS node. |
*/ |
/** |
* @todo |
* Add more IPC parameters so that we can send mount mode/flags. |
*/ |
phone = vfs_grab_phone(mp_res.triplet.fs_handle); |
rc = async_req_5_0(phone, VFS_MOUNT, |
rc = async_req_4_0(phone, VFS_MOUNT, |
(ipcarg_t) mp_res.triplet.dev_handle, |
(ipcarg_t) mp_res.triplet.index, |
(ipcarg_t) mr_res.triplet.fs_handle, |
(ipcarg_t) mr_res.triplet.dev_handle, |
(ipcarg_t) mr_res.triplet.index); |
(ipcarg_t) fs_handle, |
(ipcarg_t) dev_handle); |
vfs_release_phone(phone); |
if (rc != EOK) { |
/* Mount failed, drop references to mr_node and mp_node. */ |
vfs_node_put(mr_node); |
/* Mount failed, drop reference to mp_node. */ |
if (mp_node) |
vfs_node_put(mp_node); |
} |
/branches/dynload/uspace/srv/vfs/vfs.h |
---|
65,6 → 65,7 |
typedef enum { |
VFS_LOOKUP = VFS_LAST_CMN, |
VFS_MOUNTED, |
VFS_DESTROY, |
VFS_LAST_CLNT, /* keep this the last member of this enum */ |
} vfs_request_clnt_t; |
244,7 → 245,7 |
extern link_t fs_head; /**< List of registered file systems. */ |
extern vfs_triplet_t rootfs; /**< Root node of the root file system. */ |
extern vfs_pair_t rootfs; /**< Root file system. */ |
#define MAX_PATH_LEN (64 * 1024) |
/branches/dynload/uspace/srv/vfs/vfs_lookup.c |
---|
72,7 → 72,7 |
if (altroot) |
root = altroot; |
else |
root = (vfs_pair_t *) &rootfs; |
root = &rootfs; |
if (!root->fs_handle) |
return ENOENT; |
/branches/dynload/boot/arch/sparc64/loader/asm.S |
---|
98,6 → 98,16 |
mov %o1, %o0 |
jump_to_kernel: |
/* |
* We have copied code and now we need to guarantee cache coherence. |
* 1. Make sure that the code we have moved has drained to main memory. |
* 2. Invalidate I-cache. |
* 3. Flush instruction pipeline. |
*/ |
call icache_flush |
membar #StoreStore |
flush %i7 |
mov %o0, %l1 |
mov %o1, %o0 |
mov %o2, %o1 |
105,6 → 115,24 |
jmp %l1 ! jump to kernel |
nop |
#define ICACHE_SIZE 8192 |
#define ICACHE_LINE_SIZE 32 |
#define ICACHE_SET_BIT (1 << 13) |
#define ASI_ICACHE_TAG 0x67 |
# Flush I-cache |
icache_flush: |
set ((ICACHE_SIZE - ICACHE_LINE_SIZE) | ICACHE_SET_BIT), %g1 |
stxa %g0, [%g1] ASI_ICACHE_TAG |
0: membar #Sync |
subcc %g1, ICACHE_LINE_SIZE, %g1 |
bnz,pt %xcc, 0b |
stxa %g0, [%g1] ASI_ICACHE_TAG |
membar #Sync |
retl |
! SF Erratum #51 |
nop |
.global ofw |
ofw: |
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
/branches/dynload/boot/arch/sparc64/loader/ofwarch.c |
---|
69,18 → 69,23 |
uint64_t current_mid; |
asm volatile ("ldxa [%1] %2, %0\n" : "=r" (current_mid) : "r" (0), "i" (ASI_UPA_CONFIG)); |
asm volatile ("ldxa [%1] %2, %0\n" |
: "=r" (current_mid) |
: "r" (0), "i" (ASI_UPA_CONFIG)); |
current_mid >>= UPA_CONFIG_MID_SHIFT; |
current_mid &= UPA_CONFIG_MID_MASK; |
int cpus; |
for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node), cpus++) { |
if (ofw_get_property(node, "device_type", type_name, sizeof(type_name)) > 0) { |
for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node), |
cpus++) { |
if (ofw_get_property(node, "device_type", type_name, |
sizeof(type_name)) > 0) { |
if (strcmp(type_name, "cpu") == 0) { |
uint32_t mid; |
if (ofw_get_property(node, "upa-portid", &mid, sizeof(mid)) <= 0) |
if (ofw_get_property(node, "upa-portid", &mid, |
sizeof(mid)) <= 0) |
continue; |
if (current_mid != mid) { |
87,9 → 92,10 |
/* |
* Start secondary processor. |
*/ |
(void) ofw_call("SUNW,start-cpu", 3, 1, NULL, node, |
KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | AP_PROCESSOR); |
(void) ofw_call("SUNW,start-cpu", 3, 1, |
NULL, node, KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | |
AP_PROCESSOR); |
} |
} |
} |
/branches/dynload/boot/arch/ia64/loader/gefi/HelenOS/Makefile |
---|
36,7 → 36,7 |
clean: |
rm -f *.efi *~ *.o *.so |
rm -f *.efi *~ *.o *.so *.map *.disass *.bin |
.PHONY: install |
/branches/dynload/boot/arch/ia64/loader/Makefile |
---|
118,7 → 118,8 |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot image.map image.disasm Makefile.depend |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot image.map image.disasm Makefile.depend ../../../../image.bin ../../../../hello.efi |
make -C gefi clean |
make -C gefi/HelenOS clean |
_components.h _components.c _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) _link.ld.in |
/branches/dynload/boot/arch/arm32/loader/boot.S |
---|
39,6 → 39,11 |
b bootstrap |
jump_to_kernel: |
# |
# TODO |
# Make sure that the I-cache, D-cache and memory are mutually coherent |
# before passing control to the copied code. |
# |
bx r0 |
/branches/dynload/boot/arch/mips32/loader/asm.S |
---|
106,6 → 106,10 |
move $v0,$a1 |
jump_to_kernel: |
# .word 0x39 |
# |
# TODO |
# Make sure that the I-cache, D-cache and memory are mutually coherent |
# before passing control to the copied code. |
# |
j $a0 |
nop |
/branches/dynload/Makefile |
---|
113,7 → 113,7 |
BARCH = ia32xen |
endif |
.PHONY: all build config distclean clean |
.PHONY: all build config distclean clean cscope |
all: |
tools/config.py HelenOS.config default $(PLATFORM) $(COMPILER) $(CONFIG_DEBUG) |
145,3 → 145,8 |
-$(MAKE) -C kernel clean |
-$(MAKE) -C uspace clean |
-$(MAKE) -C boot clean |
cscope: |
-rm cscope.out |
-find kernel boot uspace -regex '^.*\.[chsS]$$' -print >srclist |
-cscope -bi srclist |