Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3597 → Rev 3596

/branches/tracing/kernel/generic/src/mm/tlb.c
134,9 → 134,7
 
void tlb_shootdown_ipi_send(void)
{
#ifndef ia64
ipi_broadcast(VECTOR_TLB_SHOOTDOWN_IPI);
#endif
}
 
/** Receive TLB shootdown message. */
/branches/tracing/kernel/generic/src/main/kinit.c
169,7 → 169,7
}
 
int rc = program_create_from_image((void *) init.tasks[i].addr,
"init-bin", &programs[i]);
&programs[i]);
 
if (rc == 0 && programs[i].task != NULL) {
/*
/branches/tracing/kernel/generic/src/main/main.c
328,7 → 328,6
* collide with another CPU coming up. To prevent this, we
* switch to this cpu's private stack prior to waking kmp up.
*/
context_save(&CPU->saved_context);
context_set(&CPU->saved_context, FADDR(main_ap_separated_stack),
(uintptr_t) CPU->stack, CPU_STACK_SIZE);
context_restore(&CPU->saved_context);
/branches/tracing/kernel/generic/src/proc/task.c
130,7 → 130,7
/** Create new task with no threads.
*
* @param as Task's address space.
* @param name Symbolic name (a copy is made).
* @param name Symbolic name.
*
* @return New task's structure.
*
148,10 → 148,7
spinlock_initialize(&ta->lock, "task_ta_lock");
list_initialize(&ta->th_head);
ta->as = as;
 
memcpy(ta->name, name, TASK_NAME_BUFLEN);
ta->name[TASK_NAME_BUFLEN - 1] = '\0';
 
ta->name = name;
atomic_set(&ta->refcount, 0);
atomic_set(&ta->lifecount, 0);
ta->context = CONTEXT;
/branches/tracing/kernel/generic/src/proc/thread.c
279,7 → 279,7
* guarantee that the task won't cease to exist during the
* call. The task's lock may not be held.
* @param flags Thread flags.
* @param name Symbolic name (a copy is made).
* @param name Symbolic name.
* @param uncounted Thread's accounting doesn't affect accumulated task
* accounting.
*
316,7 → 316,6
interrupts_restore(ipl);
memcpy(t->name, name, THREAD_NAME_BUFLEN);
t->name[THREAD_NAME_BUFLEN - 1] = '\0';
t->thread_code = func;
t->thread_arg = arg;
709,7 → 708,7
*
*/
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name,
size_t name_len, thread_id_t *uspace_thread_id)
thread_id_t *uspace_thread_id)
{
thread_t *t;
char namebuf[THREAD_NAME_BUFLEN];
716,15 → 715,10
uspace_arg_t *kernel_uarg;
int rc;
 
if (name_len > THREAD_NAME_BUFLEN - 1)
name_len = THREAD_NAME_BUFLEN - 1;
 
rc = copy_from_uspace(namebuf, uspace_name, name_len);
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN);
if (rc != 0)
return (unative_t) rc;
 
namebuf[name_len] = '\0';
 
/*
* In case of failure, kernel_uarg will be deallocated in this function.
* In case of success, kernel_uarg will be freed in uinit().
/branches/tracing/kernel/generic/src/proc/program.c
67,10 → 67,9
*
* @param as Address space containing a binary program image.
* @param entry_addr Program entry-point address in program address space.
* @param name Name to set for the program's task.
* @param p Buffer for storing program information.
*/
void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p)
void program_create(as_t *as, uintptr_t entry_addr, program_t *p)
{
as_area_t *a;
uspace_arg_t *kernel_uarg;
82,7 → 81,7
kernel_uarg->uspace_thread_arg = NULL;
kernel_uarg->uspace_uarg = NULL;
p->task = task_create(as, name);
p->task = task_create(as, "app");
ASSERT(p->task);
 
/*
107,7 → 106,6
* executable image. The task is returned in *task.
*
* @param image_addr Address of an executable program image.
* @param name Name to set for the program's task.
* @param p Buffer for storing program info. If image_addr
* points to a loader image, p->task will be set to
* NULL and EOK will be returned.
114,7 → 112,7
*
* @return EOK on success or negative error code.
*/
int program_create_from_image(void *image_addr, char *name, program_t *p)
int program_create_from_image(void *image_addr, program_t *p)
{
as_t *as;
unsigned int rc;
138,7 → 136,7
return EOK;
}
 
program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p);
program_create(as, ((elf_header_t *) image_addr)->e_entry, p);
 
return EOK;
}
145,12 → 143,10
 
/** Create a task from the program loader image.
*
* @param p Buffer for storing program info.
* @param name Name to set for the program's task.
*
* @param p Buffer for storing program info.
* @return EOK on success or negative error code.
*/
int program_create_loader(program_t *p, char *name)
int program_create_loader(program_t *p)
{
as_t *as;
unsigned int rc;
171,8 → 167,7
return ENOENT;
}
 
program_create(as, ((elf_header_t *) program_loader)->e_entry,
name, p);
program_create(as, ((elf_header_t *) program_loader)->e_entry, p);
 
return EOK;
}
193,20 → 188,16
* Creates a new task from the program loader image, connects a phone
* to it and stores the phone id into the provided buffer.
*
* @param uspace_phone_id Userspace address where to store the phone id.
* @param name Name to set on the new task (typically the same
* as the command used to execute it).
* @param uspace_phone_id Userspace address where to store the phone id.
*
* @return 0 on success or an error code from @ref errno.h.
*/
unative_t sys_program_spawn_loader(int *uspace_phone_id, char *uspace_name,
size_t name_len)
unative_t sys_program_spawn_loader(int *uspace_phone_id)
{
program_t p;
int fake_id;
int rc;
int phone_id;
char namebuf[TASK_NAME_BUFLEN];
 
fake_id = 0;
 
216,26 → 207,11
if (rc != 0)
return rc;
 
/* Cap length of name and copy it from userspace. */
 
if (name_len > THREAD_NAME_BUFLEN - 1)
name_len = THREAD_NAME_BUFLEN - 1;
 
rc = copy_from_uspace(namebuf, uspace_name, name_len);
if (rc != 0)
return (unative_t) rc;
 
namebuf[name_len] = '\0';
 
/* Allocate the phone for communicating with the new task. */
 
phone_id = phone_alloc();
if (phone_id < 0)
return ELIMIT;
 
/* Spawn the new task. */
 
rc = program_create_loader(&p, namebuf);
rc = program_create_loader(&p);
if (rc != 0)
return rc;
 
/branches/tracing/kernel/generic/include/proc/task.h
54,8 → 54,6
#include <proc/scheduler.h>
#include <udebug/udebug.h>
 
#define TASK_NAME_BUFLEN 20
 
struct thread;
 
/** Task structure. */
69,8 → 67,8
* threads.
*/
SPINLOCK_DECLARE(lock);
 
char name[TASK_NAME_BUFLEN];
char *name;
/** List of threads contained in this task. */
link_t th_head;
/** Address space. */
/branches/tracing/kernel/generic/include/proc/thread.h
259,8 → 259,7
extern slab_cache_t *fpu_context_slab;
 
/* Thread syscall prototypes. */
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg,
char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id);
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, thread_id_t *uspace_thread_id);
extern unative_t sys_thread_exit(int uspace_status);
extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);
 
/branches/tracing/kernel/generic/include/proc/program.h
52,15 → 52,12
 
extern void *program_loader;
 
extern void program_create(as_t *as, uintptr_t entry_addr, char *name,
program_t *p);
extern int program_create_from_image(void *image_addr, char *name,
program_t *p);
extern int program_create_loader(program_t *p, char *name);
extern void program_create(as_t *as, uintptr_t entry_addr, program_t *p);
extern int program_create_from_image(void *image_addr, program_t *p);
extern int program_create_loader(program_t *p);
extern void program_ready(program_t *p);
 
extern unative_t sys_program_spawn_loader(int *uspace_phone_id,
char *uspace_name, size_t name_len);
extern unative_t sys_program_spawn_loader(int *uspace_phone_id);
 
#endif
 
/branches/tracing/kernel/generic/include/synch/spinlock.h
36,7 → 36,6
#define KERN_SPINLOCK_H_
 
#include <arch/types.h>
#include <arch/barrier.h>
#include <preemption.h>
#include <atomic.h>
#include <debug.h>
/branches/tracing/kernel/arch/sparc64/include/types.h
54,8 → 54,6
 
typedef uint64_t ipl_t;
 
typedef uint64_t ioport_t;
 
typedef uint64_t unative_t;
typedef int64_t native_t;
 
/branches/tracing/kernel/arch/sparc64/include/asm.h
42,56 → 42,7
#include <arch/register.h>
#include <config.h>
#include <arch/stack.h>
#include <arch/barrier.h>
 
static inline void outb(ioport_t port, uint8_t v)
{
*((volatile uint8_t *)(port)) = v;
memory_barrier();
}
 
static inline void outw(ioport_t port, uint16_t v)
{
*((volatile uint16_t *)(port)) = v;
memory_barrier();
}
 
static inline void outl(ioport_t port, uint32_t v)
{
*((volatile uint32_t *)(port)) = v;
memory_barrier();
}
 
static inline uint8_t inb(ioport_t port)
{
uint8_t rv;
 
rv = *((volatile uint8_t *)(port));
memory_barrier();
 
return rv;
}
 
static inline uint16_t inw(ioport_t port)
{
uint16_t rv;
 
rv = *((volatile uint16_t *)(port));
memory_barrier();
 
return rv;
}
 
static inline uint32_t inl(ioport_t port)
{
uint32_t rv;
 
rv = *((volatile uint32_t *)(port));
memory_barrier();
 
return rv;
}
 
/** Read Processor State register.
*
* @return Value of PSTATE register.
/branches/tracing/kernel/arch/sparc64/include/drivers/ns16550.h
35,7 → 35,67
#ifndef KERN_sparc64_NS16550_H_
#define KERN_sparc64_NS16550_H_
 
#include <arch/types.h>
#include <arch/drivers/kbd.h>
 
/* NS16550 registers */
#define RBR_REG 0 /** Receiver Buffer Register. */
#define IER_REG 1 /** Interrupt Enable Register. */
#define IIR_REG 2 /** Interrupt Ident Register (read). */
#define FCR_REG 2 /** FIFO control register (write). */
#define LCR_REG 3 /** Line Control register. */
#define LSR_REG 5 /** Line Status Register. */
 
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */
 
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */
 
/** Structure representing the ns16550 device. */
typedef struct {
devno_t devno;
volatile uint8_t *reg; /** Memory mapped registers of the ns16550. */
} ns16550_t;
 
static inline uint8_t ns16550_rbr_read(ns16550_t *dev)
{
return dev->reg[RBR_REG];
}
 
static inline uint8_t ns16550_ier_read(ns16550_t *dev)
{
return dev->reg[IER_REG];
}
 
static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v)
{
dev->reg[IER_REG] = v;
}
 
static inline uint8_t ns16550_iir_read(ns16550_t *dev)
{
return dev->reg[IIR_REG];
}
 
static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v)
{
dev->reg[FCR_REG] = v;
}
 
static inline uint8_t ns16550_lcr_read(ns16550_t *dev)
{
return dev->reg[LCR_REG];
}
 
static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v)
{
dev->reg[LCR_REG] = v;
}
 
static inline uint8_t ns16550_lsr_read(ns16550_t *dev)
{
return dev->reg[LSR_REG];
}
 
#endif
 
/** @}
/branches/tracing/kernel/arch/sparc64/src/drivers/kbd.c
147,7 → 147,7
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_init(devno, inr, (ioport_t)vaddr);
ns16550_init(devno, inr, vaddr);
break;
#endif
default:
/branches/tracing/kernel/arch/ia64/include/asm.h
39,11 → 39,10
#include <arch/types.h>
#include <arch/register.h>
 
typedef uint64_t ioport_t;
 
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL
 
static inline void outb(ioport_t port,uint8_t v)
static inline void outb(uint64_t port,uint8_t v)
{
*((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
50,7 → 49,7
asm volatile ("mf\n" ::: "memory");
}
 
static inline void outw(ioport_t port,uint16_t v)
static inline void outw(uint64_t port,uint16_t v)
{
*((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
57,7 → 56,7
asm volatile ("mf\n" ::: "memory");
}
 
static inline void outl(ioport_t port,uint32_t v)
static inline void outl(uint64_t port,uint32_t v)
{
*((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
66,7 → 65,7
 
 
 
static inline uint8_t inb(ioport_t port)
static inline uint8_t inb(uint64_t port)
{
asm volatile ("mf\n" ::: "memory");
 
73,7 → 72,7
return *((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
}
 
static inline uint16_t inw(ioport_t port)
static inline uint16_t inw(uint64_t port)
{
asm volatile ("mf\n" ::: "memory");
 
80,7 → 79,7
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xffE) | ( (port >> 2) << 12 ))));
}
 
static inline uint32_t inl(ioport_t port)
static inline uint32_t inl(uint64_t port)
{
asm volatile ("mf\n" ::: "memory");
 
99,14 → 98,9
{
uint64_t v;
 
//I'm not sure why but this code bad inlines in scheduler,
//so THE shifts about 16B and causes kernel panic
//asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
//return v;
asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
//this code have the same meaning but inlines well
asm volatile ("mov %0 = r12" : "=r" (v) );
return v & (~(STACK_SIZE-1));
return v;
}
 
/** Return Processor State Register.
158,16 → 152,6
return v;
}
 
static inline uint64_t cr64_read(void)
{
uint64_t v;
asm volatile ("mov %0 = cr64\n" : "=r" (v));
return v;
}
 
 
/** Write ITC (Interval Timer Counter) register.
*
* @param v New counter value.
/branches/tracing/kernel/arch/ia64/include/mm/page.h
46,20 → 46,8
/** Bit width of the TLB-locked portion of kernel address space. */
#define KERNEL_PAGE_WIDTH 28 /* 256M */
#define IO_PAGE_WIDTH 26 /* 64M */
#define FW_PAGE_WIDTH 28 /* 256M */
 
/** Staticly mapped IO spaces */
 
/* Firmware area (bellow 4GB in phys mem) */
#define FW_OFFSET 0x00000000F0000000
/* Legacy IO space */
#define IO_OFFSET 0x0001000000000000
/* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000*/
#define VIO_OFFSET 0x0002000000000000
 
 
 
 
#define PPN_SHIFT 12
 
#define VRN_SHIFT 61
/branches/tracing/kernel/arch/ia64/include/drivers/it.h
41,7 → 41,7
* from firmware.
*
*/
#define IT_DELTA it_delta
#define IT_DELTA 100000
 
extern void it_init(void);
 
/branches/tracing/kernel/arch/ia64/include/bootinfo.h
29,8 → 29,8
#ifndef KERN_ia64_BOOTINFO_H_
#define KERN_ia64_BOOTINFO_H_
 
#define BOOTINFO_ADDRESS 0x4401000
 
 
#define CONFIG_INIT_TASKS 32
 
typedef struct {
46,12 → 46,6
 
typedef struct {
binit_t taskmap;
 
unsigned long * sapic;
unsigned long sys_freq;
unsigned long freq_scale;
unsigned int wakeup_intno;
 
} bootinfo_t;
 
extern bootinfo_t *bootinfo;
/branches/tracing/kernel/arch/ia64/include/cpu.h
38,7 → 38,6
#include <arch/types.h>
#include <arch/register.h>
#include <arch/asm.h>
#include <arch/bootinfo.h>
 
#define FAMILY_ITANIUM 0x7
#define FAMILY_ITANIUM2 0x1f
64,33 → 63,6
return v;
}
 
 
#define CR64_ID_SHIFT 24
#define CR64_ID_MASK 0xff000000
#define CR64_EID_SHIFT 16
#define CR64_EID_MASK 0xff0000
 
static inline int ia64_get_cpu_id(void)
{
uint64_t cr64=cr64_read();
return ((CR64_ID_MASK)&cr64)>>CR64_ID_SHIFT;
}
 
static inline int ia64_get_cpu_eid(void)
{
uint64_t cr64=cr64_read();
return ((CR64_EID_MASK)&cr64)>>CR64_EID_SHIFT;
}
 
 
 
static inline void ipi_send_ipi(int id,int eid,int intno)
{
(bootinfo->sapic)[2*(id*256+eid)]=intno;
}
 
 
 
#endif
 
/** @}
/branches/tracing/kernel/arch/ia64/include/atomic.h
51,20 → 51,6
return v;
}
 
 
static inline uint64_t test_and_set(atomic_t *val) {
uint64_t v;
asm volatile (
"movl %0=0x01;;\n"
"xchg8 %0=%1,%0;;\n"
: "=r" (v),"+m" (val->count)
);
return v;
}
 
 
static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); }
static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); }
 
/branches/tracing/kernel/arch/ia64/Makefile.inc
82,7 → 82,6
arch/$(ARCH)/src/mm/vhpt.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/smp/smp.c \
arch/$(ARCH)/src/drivers/it.c
 
ifeq ($(MACHINE),ski)
99,7 → 98,3
BFD = binary
endif
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
 
/branches/tracing/kernel/arch/ia64/src/smp/smp.c
File deleted
/branches/tracing/kernel/arch/ia64/src/mm/frame.c
42,31 → 42,20
* for real ia64 systems that provide memory map.
*/
#define MEMORY_SIZE (64 * 1024 * 1024)
#define MEMORY_BASE (0 * 64 * 1024 * 1024)
#define MEMORY_BASE (64 * 1024 * 1024)
 
#define ONE_TO_ONE_MAPPING_SIZE (256*1048576) // Mapped at start
 
#define ROM_BASE 0xa0000 //For ski
#define ROM_SIZE (384 * 1024) //For ski
void poke_char(int x,int y,char ch, char c);
 
uintptr_t last_frame;
 
void frame_arch_init(void)
{
 
if(config.cpu_active==1)
{
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0);
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0);
/*
* Blacklist ROM regions.
*/
//frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE));
 
frame_mark_unavailable(ADDR2PFN(0), SIZE2FRAMES(1048576));
last_frame=SIZE2FRAMES((VRN_KERNEL<<VRN_SHIFT)+ONE_TO_ONE_MAPPING_SIZE);
}
/*
* Blacklist ROM regions.
*/
frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE));
}
 
/** @}
/branches/tracing/kernel/arch/ia64/src/mm/page.c
47,7 → 47,6
#include <arch/asm.h>
#include <arch/barrier.h>
#include <memstr.h>
#include <align.h>
 
static void set_environment(void);
 
263,27 → 262,5
v->present.tag.tag_word = tag;
}
 
extern uintptr_t last_frame;
 
 
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) {
uintptr_t addr = PFN2ADDR(i);
page_mapping_insert(AS_KERNEL, virtaddr + addr, physaddr + addr, PAGE_NOT_CACHEABLE | PAGE_WRITE);
}
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}
 
 
 
/** @}
*/
/branches/tracing/kernel/arch/ia64/src/drivers/it.c
46,16 → 46,6
 
#define IT_SERVICE_CLOCKS 64
 
#define FREQ_NUMERATOR_SHIFT 32
#define FREQ_NUMERATOR_MASK 0xffffffff00000000LL
 
#define FREQ_DENOMINATOR_SHIFT 0
#define FREQ_DENOMINATOR_MASK 0xffffffffLL
 
 
uint64_t it_delta;
 
 
static irq_t it_irq;
 
static irq_ownership_t it_claim(void);
65,25 → 55,14
void it_init(void)
{
cr_itv_t itv;
if(config.cpu_active==1)
{
irq_initialize(&it_irq);
it_irq.inr = INTERRUPT_TIMER;
it_irq.devno = device_assign_devno();
it_irq.claim = it_claim;
it_irq.handler = it_interrupt;
irq_register(&it_irq);
uint64_t base_freq;
base_freq = ((bootinfo->freq_scale) & FREQ_NUMERATOR_MASK) >> FREQ_NUMERATOR_SHIFT;
base_freq *= bootinfo->sys_freq;
base_freq /= ((bootinfo->freq_scale) & FREQ_DENOMINATOR_MASK) >> FREQ_DENOMINATOR_SHIFT;
it_delta = base_freq /HZ;
}
 
irq_initialize(&it_irq);
it_irq.inr = INTERRUPT_TIMER;
it_irq.devno = device_assign_devno();
it_irq.claim = it_claim;
it_irq.handler = it_interrupt;
irq_register(&it_irq);
 
/* initialize Interval Timer external interrupt vector */
itv.value = itv_read();
itv.vector = INTERRUPT_TIMER;
/branches/tracing/kernel/arch/ia64/src/ia64.c
54,17 → 54,7
#include <arch/drivers/ega.h>
#include <arch/bootinfo.h>
#include <genarch/kbd/i8042.h>
#include <genarch/kbd/ns16550.h>
#include <smp/smp.h>
#include <smp/ipi.h>
#include <arch/atomic.h>
#include <panic.h>
#include <print.h>
 
/*NS16550 as a COM 1*/
#define NS16550_IRQ 4
#define NS16550_PORT 0x3f8
 
bootinfo_t *bootinfo;
 
void arch_pre_main(void)
112,15 → 102,12
 
void arch_post_mm_init(void)
{
if(config.cpu_active==1)
{
irq_init(INR_COUNT, INR_COUNT);
irq_init(INR_COUNT, INR_COUNT);
#ifdef SKI
ski_init_console();
ski_init_console();
#else
ega_init();
ega_init();
#endif
}
it_init();
}
 
140,9 → 127,6
{
while (1) {
i8042_poll();
#ifdef CONFIG_NS16550
ns16550_poll();
#endif
thread_usleep(POLL_INTERVAL);
}
}
151,7 → 135,7
void arch_post_smp_init(void)
{
 
{
if (config.cpu_active == 1) {
/*
* Create thread that polls keyboard.
*/
169,10 → 153,6
/* keyboard controller */
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE);
 
#ifdef CONFIG_NS16550
ns16550_init(kbd, NS16550_IRQ, NS16550_PORT); // as a COM 1
#else
#endif
thread_t *t;
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
184,7 → 164,6
}
}
 
 
/** Enter userspace and never return. */
void userspace(uspace_arg_t *kernel_uarg)
{
245,7 → 224,7
 
void arch_reboot(void)
{
outb(0x64,0xfe);
// TODO
while (1);
}
 
/branches/tracing/kernel/arch/ia64/src/start.S
39,10 → 39,12
#define KERNEL_TRANSLATION_D 0x0010000000000661
#define KERNEL_TRANSLATION_VIO 0x0010000000000671
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671
#define KERNEL_TRANSLATION_FW 0x00100000F0000671
#define VIO_OFFSET 0x0002000000000000
 
#define IO_OFFSET 0x0001000000000000
 
 
 
.section K_TEXT_START, "ax"
 
.global kernel_image_start
51,18 → 53,6
kernel_image_start:
.auto
 
#identifi self(CPU) in OS structures by ID / EID
mov r9=cr64
mov r10=1
movl r12=0xffffffff
movl r8=cpu_by_id_eid_list
and r8=r8,r12
shr r9=r9,16
add r8=r8,r9
st1 [r8]=r10
 
 
 
mov psr.l = r0
srlz.i
srlz.d
124,25 → 114,8
itr.d dtr[r7] = r10
 
 
#setup mapping for fimware arrea (also SAPIC)
mov r11 = cr.itir ;;
movl r10 = ~0xfc;;
and r10 =r10 , r11 ;;
movl r11 = (FW_PAGE_WIDTH << PS_SHIFT);;
or r10 =r10 , r11 ;;
mov cr.itir = r10;;
 
 
movl r7 = 3
movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET
mov cr.ifa = r8
movl r10 = (KERNEL_TRANSLATION_FW)
itr.d dtr[r7] = r10
 
 
 
 
 
# initialize PSR
movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK) /* Enable paging */
mov r9 = psr
169,12 → 142,6
 
# switch to register bank 1
bsw.1
 
#Am'I BSP or AP
movl r20=bsp_started;;
ld8 r20=[r20];;
cmp.eq p3,p2=r20,r0;;
 
# initialize register stack
mov ar.rsc = r0
193,35 → 160,25
movl r1 = _hardcoded_load_address
/*
* Initialize hardcoded_* variables. Do only BSP
* Initialize hardcoded_* variables.
*/
(p3) movl r14 = _hardcoded_ktext_size
(p3) movl r15 = _hardcoded_kdata_size
(p3) movl r16 = _hardcoded_load_address ;;
(p3) addl r17 = @gprel(hardcoded_ktext_size), gp
(p3) addl r18 = @gprel(hardcoded_kdata_size), gp
(p3) addl r19 = @gprel(hardcoded_load_address), gp
(p3) addl r21 = @gprel(bootinfo), gp
movl r14 = _hardcoded_ktext_size
movl r15 = _hardcoded_kdata_size
movl r16 = _hardcoded_load_address ;;
addl r17 = @gprel(hardcoded_ktext_size), gp
addl r18 = @gprel(hardcoded_kdata_size), gp
addl r19 = @gprel(hardcoded_load_address), gp
addl r21 = @gprel(bootinfo), gp
;;
(p3) st8 [r17] = r14
(p3) st8 [r18] = r15
(p3) st8 [r19] = r16
(p3) st8 [r21] = r20
st8 [r17] = r14
st8 [r18] = r15
st8 [r19] = r16
st8 [r21] = r20
 
ssm (1 << 19) ;; /* Disable f32 - f127 */
srlz.i
srlz.d ;;
 
(p2) movl r18 = main_ap ;;
(p2) mov b1 = r18 ;;
(p2) br.call.sptk.many b0 = b1
 
#Mark that BSP is on
mov r20=1;;
movl r21=bsp_started;;
st8 [r21]=r20;;
 
 
br.call.sptk.many b0 = arch_pre_main
 
movl r18 = main_bsp ;;
231,46 → 188,3
 
0:
br 0b
.align 4096
 
kernel_image_ap_start:
.auto
#identifi self(CPU) in OS structures by ID / EID
mov r9=cr64
mov r10=1
movl r12=0xffffffff
movl r8=cpu_by_id_eid_list
and r8=r8,r12
shr r9=r9,16
add r8=r8,r9
st1 [r8]=r10
#wait for wakeup sychro signal (#3 in cpu_by_id_eid_list)
kernel_image_ap_start_loop:
movl r11=kernel_image_ap_start_loop
and r11=r11,r12
mov b1 = r11
 
ld1 r20=[r8];;
movl r21=3;;
cmp.eq p2,p3=r20,r21;;
(p3)br.call.sptk.many b0 = b1
 
movl r11=kernel_image_start
and r11=r11,r12
mov b1 = r11
br.call.sptk.many b0 = b1
 
 
.align 16
.global bsp_started
bsp_started:
.space 8
 
 
.align 4096
.global cpu_by_id_eid_list
cpu_by_id_eid_list:
.space 65536
 
 
/branches/tracing/kernel/arch/ppc32/src/asm.S
66,9 → 66,9
mr sp, r4
 
# %r6 is defined to hold pcb_ptr - set it to 0
# %r3 is defined to hold pcb_ptr - set it to 0
 
xor r6, r6, r6
xor r3, r3, r3
# jump to userspace
/branches/tracing/kernel/arch/ppc32/src/mm/tlb.c
35,7 → 35,6
#include <mm/tlb.h>
#include <arch/mm/tlb.h>
#include <arch/interrupt.h>
#include <interrupt.h>
#include <mm/as.h>
#include <arch.h>
#include <print.h>
97,6 → 96,7
return NULL;
case AS_PF_FAULT:
page_table_lock(as, lock);
printf("Page fault.\n");
*pfrc = rc;
return NULL;
default:
117,10 → 117,6
s = get_symtab_entry(istate->lr);
if (s)
sym2 = s;
 
fault_if_from_uspace(istate,
"%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr,
istate->pc, symbol, sym2);
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr,
istate->pc, symbol, sym2);
}
/branches/tracing/kernel/arch/mips32/src/mm/tlb.c
429,6 → 429,7
break;
case AS_PF_FAULT:
page_table_lock(AS, true);
printf("Page fault.\n");
*pfrc = AS_PF_FAULT;
return NULL;
break;
/branches/tracing/kernel/arch/ppc64/src/mm/page.c
103,6 → 103,7
return NULL;
case AS_PF_FAULT:
page_table_lock(as, lock);
printf("Page fault.\n");
*pfrc = rc;
return NULL;
default:
/branches/tracing/kernel/kernel.config
118,7 → 118,7
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_BPP (choice)
 
# Support for SMP
! [ARCH=ia32|ARCH=amd64|ARCH=ia32xen|ARCH=sparc64|ARCH=ia64] CONFIG_SMP (y/n)
! [ARCH=ia32|ARCH=amd64|ARCH=ia32xen|ARCH=sparc64] CONFIG_SMP (y/n)
 
# Improved support for hyperthreading
! [(ARCH=ia32|ARCH=amd64|ARCH=ia32xen)&CONFIG_SMP=y] CONFIG_HT (y/n)
139,9 → 139,8
! [ARCH=sparc64] CONFIG_Z8530 (y/n)
 
# Support for NS16550 serial port
! [ARCH=sparc64|ARCH=ia64] CONFIG_NS16550 (y/n)
! [ARCH=sparc64] CONFIG_NS16550 (y/n)
 
 
# Virtually indexed D-cache support
! [ARCH=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
 
/branches/tracing/kernel/genarch/include/kbd/ns16550.h
48,75 → 48,7
extern irq_ownership_t ns16550_claim(void);
extern void ns16550_irq_handler(irq_t *irq, void *arg, ...);
 
#include <arch/types.h>
#ifndef ia64
#include <arch/drivers/kbd.h>
#endif
/* NS16550 registers */
#define RBR_REG 0 /** Receiver Buffer Register. */
#define IER_REG 1 /** Interrupt Enable Register. */
#define IIR_REG 2 /** Interrupt Ident Register (read). */
#define FCR_REG 2 /** FIFO control register (write). */
#define LCR_REG 3 /** Line Control register. */
#define LSR_REG 5 /** Line Status Register. */
 
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */
 
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */
 
/** Structure representing the ns16550 device. */
typedef struct {
devno_t devno;
volatile ioport_t io_port; /** Memory mapped registers of the ns16550. */
} ns16550_t;
 
static inline uint8_t ns16550_rbr_read(ns16550_t *dev)
{
return inb(dev->io_port+RBR_REG);
}
static inline void ns16550_rbr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port+RBR_REG,v);
}
 
static inline uint8_t ns16550_ier_read(ns16550_t *dev)
{
return inb(dev->io_port+IER_REG);
}
 
static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port+IER_REG,v);
}
 
static inline uint8_t ns16550_iir_read(ns16550_t *dev)
{
return inb(dev->io_port+IIR_REG);
}
 
static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port+FCR_REG,v);
}
 
static inline uint8_t ns16550_lcr_read(ns16550_t *dev)
{
return inb(dev->io_port+LCR_REG);
}
 
static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port+LCR_REG,v);
}
 
static inline uint8_t ns16550_lsr_read(ns16550_t *dev)
{
return inb(dev->io_port+LSR_REG);
}
 
 
 
#endif
 
/** @}
*/
/branches/tracing/kernel/genarch/src/kbd/key.c
39,13 → 39,9
#ifdef CONFIG_I8042
#include <genarch/kbd/scanc_pc.h>
#endif
 
#if (defined(sparc64))
#if (defined(CONFIG_Z8530) || defined(CONFIG_NS16550))
#include <genarch/kbd/scanc_sun.h>
#endif
#endif
 
#include <synch/spinlock.h>
#include <console/chardev.h>
#include <macros.h>
/branches/tracing/kernel/genarch/src/kbd/ns16550.c
38,10 → 38,8
#include <genarch/kbd/key.h>
#include <genarch/kbd/scanc.h>
#include <genarch/kbd/scanc_sun.h>
#ifndef ia64
#include <arch/drivers/kbd.h>
#include <arch/drivers/ns16550.h>
#endif
#include <ddi/irq.h>
#include <ipc/irq.h>
#include <cpu.h>
111,13 → 109,13
* @param inr Interrupt number.
* @param vaddr Virtual address of device's registers.
*/
void ns16550_init(devno_t devno, inr_t inr, ioport_t port)
void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr)
{
chardev_initialize("ns16550_kbd", &kbrd, &ops);
stdin = &kbrd;
ns16550.devno = devno;
ns16550.io_port = port;
ns16550.reg = (uint8_t *) vaddr;
irq_initialize(&ns16550_irq);
ns16550_irq.devno = devno;
127,21 → 125,10
irq_register(&ns16550_irq);
sysinfo_set_item_val("kbd", NULL, true);
#ifndef ia64
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
#endif
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, inr);
sysinfo_set_item_val("kbd.address.virtual", NULL, port);
 
#ifdef ia64
uint8_t c;
c = ns16550_lcr_read(&ns16550);
ns16550_lcr_write(&ns16550, 0x80 | c);
ns16550_rbr_write(&ns16550, 0x0c);
ns16550_ier_write(&ns16550, 0x00);
ns16550_lcr_write(&ns16550, c);
#endif
sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr);
ns16550_grab();
}
165,7 → 152,6
{
}
 
 
char ns16550_key_read(chardev_t *d)
{
char ch;
175,7 → 161,6
while (!(ns16550_lsr_read(&ns16550) & LSR_DATA_READY))
;
x = ns16550_rbr_read(&ns16550);
#ifndef ia64
if (x != IGNORE_CODE) {
if (x & KEY_RELEASE)
key_released(x ^ KEY_RELEASE);
182,15 → 167,6
else
active_read_key_pressed(x);
}
#else
extern chardev_t kbrd;
if(x != 0x0d) {
if(x == 0x7f)
x = '\b';
chardev_push_character(&kbrd, x);
}
#endif
 
}
return ch;
}
225,7 → 201,6
uint8_t x;
x = ns16550_rbr_read(&ns16550);
#ifndef ia64
if (x != IGNORE_CODE) {
if (x & KEY_RELEASE)
key_released(x ^ KEY_RELEASE);
232,15 → 207,6
else
key_pressed(x);
}
#else
extern chardev_t kbrd;
if(x != 0x0d) {
if (x == 0x7f)
x = '\b';
chardev_push_character(&kbrd, x);
}
#endif
 
}
}
 
/branches/tracing/tools/mkfat.py
36,8 → 36,6
import xstruct
import array
 
exclude_names = set(['.svn'])
 
def align_up(size, alignment):
"Return size aligned up to alignment"
55,11 → 53,11
for name in os.listdir(root):
canon = os.path.join(root, name)
if (os.path.isfile(canon) and (not name in exclude_names)):
if (os.path.isfile(canon)):
size += align_up(os.path.getsize(canon), cluster_size)
files += 1
if (os.path.isdir(canon) and (not name in exclude_names)):
if (os.path.isdir(canon)):
size += subtree_size(canon, cluster_size, dirent_size)
files += 1
288,11 → 286,11
for name in os.listdir(root):
canon = os.path.join(root, name)
if (os.path.isfile(canon) and (not name in exclude_names)):
if (os.path.isfile(canon)):
rv = write_file(canon, outf, cluster_size, data_start, fat, reserved_clusters)
directory.append(create_dirent(name, False, rv[0], rv[1]))
if (os.path.isdir(canon) and (not name in exclude_names)):
if (os.path.isdir(canon)):
rv = recursion(False, canon, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster)
directory.append(create_dirent(name, True, rv[0], rv[1]))
353,6 → 351,7
return
fat16_clusters = 4096
min_cluster_size = 1024
sector_size = 512
cluster_size = 4096
364,7 → 363,7
# Make sure the filesystem is large enought for FAT16
size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size
while (size / cluster_size < fat16_clusters):
if (cluster_size > sector_size):
if (cluster_size > min_cluster_size):
cluster_size /= 2
size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size
else:
/branches/tracing/tools/mktmpfs.py
34,8 → 34,6
import os
import xstruct
 
exclude_names = set(['.svn'])
 
HEADER = """little:
char tag[5] /* 'TMPFS' */
"""
72,7 → 70,7
for name in os.listdir(root):
canon = os.path.join(root, name)
if (os.path.isfile(canon) and (not name in exclude_names)):
if (os.path.isfile(canon)):
size = os.path.getsize(canon)
dentry = xstruct.create(DENTRY_FILE % len(name))
91,7 → 89,7
rd += len(data)
inf.close()
if (os.path.isdir(canon) and (not name in exclude_names)):
if (os.path.isdir(canon)):
dentry = xstruct.create(DENTRY_DIRECTORY % len(name))
dentry.kind = TMPFS_DIRECTORY
dentry.fname_len = len(name)
/branches/tracing/uspace/app/debug/main.c
113,7 → 113,7
int rc;
 
/* Spawn a program loader */
ldr = loader_spawn(path);
ldr = loader_spawn();
if (ldr == NULL)
return 0;
 
/branches/tracing/uspace/app/tester/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/app/trace/trace.c
516,7 → 516,7
int rc;
 
/* Spawn a program loader */
ldr = loader_spawn(path);
ldr = loader_spawn();
if (ldr == NULL)
return 0;
 
/branches/tracing/uspace/app/trace/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/app/tetris/Makefile
1,5 → 1,3
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/app/klog/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/lib/libfs/libfs.c
191,7 → 191,7
}
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(dev_handle, lflag);
nodep = ops->create(lflag);
else
nodep = ops->node_get(dev_handle,
index);
262,7 → 262,7
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(dev_handle, lflag);
nodep = ops->create(lflag);
else
nodep = ops->node_get(dev_handle, index);
if (nodep) {
/branches/tracing/uspace/lib/libfs/libfs.h
45,7 → 45,7
void * (* match)(void *, const char *);
void * (* node_get)(dev_handle_t, fs_index_t);
void (* node_put)(void *);
void * (* create)(dev_handle_t, int);
void * (* create)(int);
int (* destroy)(void *);
bool (* link)(void *, void *, const char *);
int (* unlink)(void *, void *);
/branches/tracing/uspace/lib/libfs/Makefile
30,8 → 30,6
## Common compiler flags
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../libc
## Setup toolchain
#
/branches/tracing/uspace/lib/softfloat/Makefile
29,8 → 29,6
## Common compiler flags
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../libc
## Setup toolchain
#
/branches/tracing/uspace/lib/libblock/libblock.c
48,7 → 48,6
#include <assert.h>
#include <futex.h>
#include <libadt/list.h>
#include <libadt/hash_table.h>
 
/** Lock protecting the device connection list */
static futex_t dcl_lock = FUTEX_INITIALIZER;
55,18 → 54,7
/** Device connection list head. */
static LIST_INITIALIZE(dcl_head);
 
#define CACHE_BUCKETS_LOG2 10
#define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2)
 
typedef struct {
futex_t lock;
size_t block_size; /**< Block size. */
unsigned block_count; /**< Total number of blocks. */
hash_table_t block_hash;
link_t free_head;
} cache_t;
 
typedef struct {
link_t link;
int dev_handle;
int dev_phone;
75,7 → 63,6
void *bb_buf;
off_t bb_off;
size_t bb_size;
cache_t *cache;
} devcon_t;
 
static devcon_t *devcon_search(dev_handle_t dev_handle)
95,7 → 82,7
}
 
static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area,
size_t com_size)
size_t com_size, void *bb_buf, off_t bb_off, size_t bb_size)
{
link_t *cur;
devcon_t *devcon;
109,10 → 96,9
devcon->dev_phone = dev_phone;
devcon->com_area = com_area;
devcon->com_size = com_size;
devcon->bb_buf = NULL;
devcon->bb_off = 0;
devcon->bb_size = 0;
devcon->cache = NULL;
devcon->bb_buf = bb_buf;
devcon->bb_off = bb_off;
devcon->bb_size = bb_size;
 
futex_down(&dcl_lock);
for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
135,15 → 121,23
futex_up(&dcl_lock);
}
 
int block_init(dev_handle_t dev_handle, size_t com_size)
int
block_init(dev_handle_t dev_handle, size_t com_size, off_t bb_off,
size_t bb_size)
{
int rc;
int dev_phone;
void *com_area;
void *bb_buf;
bb_buf = malloc(bb_size);
if (!bb_buf)
return ENOMEM;
com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (!com_area) {
free(bb_buf);
return ENOMEM;
}
dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
150,6 → 144,7
DEVMAP_CONNECT_TO_DEVICE, dev_handle);
 
if (dev_phone < 0) {
free(bb_buf);
munmap(com_area, com_size);
return dev_phone;
}
157,18 → 152,29
rc = ipc_share_out_start(dev_phone, com_area,
AS_AREA_READ | AS_AREA_WRITE);
if (rc != EOK) {
free(bb_buf);
munmap(com_area, com_size);
ipc_hangup(dev_phone);
return rc;
}
rc = devcon_add(dev_handle, dev_phone, com_area, com_size);
rc = devcon_add(dev_handle, dev_phone, com_area, com_size, bb_buf,
bb_off, bb_size);
if (rc != EOK) {
free(bb_buf);
munmap(com_area, com_size);
ipc_hangup(dev_phone);
return rc;
}
 
off_t bufpos = 0;
size_t buflen = 0;
if (!block_read(dev_handle, &bufpos, &buflen, &bb_off,
bb_buf, bb_size, bb_size)) {
block_fini(dev_handle);
return EIO; /* XXX real error code */
}
return EOK;
}
 
179,14 → 185,7
devcon_remove(devcon);
 
if (devcon->bb_buf)
free(devcon->bb_buf);
 
if (devcon->cache) {
hash_table_destroy(&devcon->cache->block_hash);
free(devcon->cache);
}
 
free(devcon->bb_buf);
munmap(devcon->com_area, devcon->com_size);
ipc_hangup(devcon->dev_phone);
 
193,35 → 192,6
free(devcon);
}
 
int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size)
{
void *bb_buf;
int rc;
 
devcon_t *devcon = devcon_search(dev_handle);
if (!devcon)
return ENOENT;
if (devcon->bb_buf)
return EEXIST;
bb_buf = malloc(size);
if (!bb_buf)
return ENOMEM;
off_t bufpos = 0;
size_t buflen = 0;
rc = block_read(dev_handle, &bufpos, &buflen, &off,
bb_buf, size, size);
if (rc != EOK) {
free(bb_buf);
return rc;
}
devcon->bb_buf = bb_buf;
devcon->bb_off = off;
devcon->bb_size = size;
 
return EOK;
}
 
void *block_bb_get(dev_handle_t dev_handle)
{
devcon_t *devcon = devcon_search(dev_handle);
229,208 → 199,6
return devcon->bb_buf;
}
 
static hash_index_t cache_hash(unsigned long *key)
{
return *key & (CACHE_BUCKETS - 1);
}
 
static int cache_compare(unsigned long *key, hash_count_t keys, link_t *item)
{
block_t *b = hash_table_get_instance(item, block_t, hash_link);
return b->boff == *key;
}
 
static void cache_remove_callback(link_t *item)
{
}
 
static hash_table_operations_t cache_ops = {
.hash = cache_hash,
.compare = cache_compare,
.remove_callback = cache_remove_callback
};
 
int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks)
{
devcon_t *devcon = devcon_search(dev_handle);
cache_t *cache;
if (!devcon)
return ENOENT;
if (devcon->cache)
return EEXIST;
cache = malloc(sizeof(cache_t));
if (!cache)
return ENOMEM;
futex_initialize(&cache->lock, 1);
list_initialize(&cache->free_head);
cache->block_size = size;
cache->block_count = blocks;
 
if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
&cache_ops)) {
free(cache);
return ENOMEM;
}
 
devcon->cache = cache;
return EOK;
}
 
static bool cache_can_grow(cache_t *cache)
{
return true;
}
 
static void block_initialize(block_t *b)
{
futex_initialize(&b->lock, 1);
b->refcnt = 1;
b->dirty = false;
rwlock_initialize(&b->contents_lock);
link_initialize(&b->free_link);
link_initialize(&b->hash_link);
}
 
/** Instantiate a block in memory and get a reference to it.
*
* @param dev_handle Device handle of the block device.
* @param boff Block offset.
* @param flags If BLOCK_FLAGS_NOREAD is specified, block_get()
* will not read the contents of the block from the
* device.
*
* @return Block structure.
*/
block_t *block_get(dev_handle_t dev_handle, bn_t boff, int flags)
{
devcon_t *devcon;
cache_t *cache;
block_t *b;
link_t *l;
unsigned long key = boff;
devcon = devcon_search(dev_handle);
 
assert(devcon);
assert(devcon->cache);
cache = devcon->cache;
futex_down(&cache->lock);
l = hash_table_find(&cache->block_hash, &key);
if (l) {
/*
* We found the block in the cache.
*/
b = hash_table_get_instance(l, block_t, hash_link);
futex_down(&b->lock);
if (b->refcnt++ == 0)
list_remove(&b->free_link);
futex_up(&b->lock);
futex_up(&cache->lock);
} else {
/*
* The block was not found in the cache.
*/
int rc;
off_t bufpos = 0;
size_t buflen = 0;
off_t pos = boff * cache->block_size;
bool sync = false;
 
if (cache_can_grow(cache)) {
/*
* We can grow the cache by allocating new blocks.
* Should the allocation fail, we fail over and try to
* recycle a block from the cache.
*/
b = malloc(sizeof(block_t));
if (!b)
goto recycle;
b->data = malloc(cache->block_size);
if (!b->data) {
free(b);
goto recycle;
}
} else {
/*
* Try to recycle a block from the free list.
*/
unsigned long temp_key;
recycle:
assert(!list_empty(&cache->free_head));
l = cache->free_head.next;
list_remove(l);
b = hash_table_get_instance(l, block_t, hash_link);
sync = b->dirty;
temp_key = b->boff;
hash_table_remove(&cache->block_hash, &temp_key, 1);
}
 
block_initialize(b);
b->dev_handle = dev_handle;
b->size = cache->block_size;
b->boff = boff;
hash_table_insert(&cache->block_hash, &key, &b->hash_link);
 
/*
* Lock the block before releasing the cache lock. Thus we don't
* kill concurent operations on the cache while doing I/O on the
* block.
*/
futex_down(&b->lock);
futex_up(&cache->lock);
 
if (sync) {
/*
* The block is dirty and needs to be written back to
* the device before we can read in the new contents.
*/
abort(); /* TODO: block_write() */
}
if (!(flags & BLOCK_FLAGS_NOREAD)) {
/*
* The block contains old or no data. We need to read
* the new contents from the device.
*/
rc = block_read(dev_handle, &bufpos, &buflen, &pos,
b->data, cache->block_size, cache->block_size);
assert(rc == EOK);
}
 
futex_up(&b->lock);
}
return b;
}
 
/** Release a reference to a block.
*
* If the last reference is dropped, the block is put on the free list.
*
* @param block Block of which a reference is to be released.
*/
void block_put(block_t *block)
{
devcon_t *devcon = devcon_search(block->dev_handle);
cache_t *cache;
 
assert(devcon);
assert(devcon->cache);
 
cache = devcon->cache;
futex_down(&cache->lock);
futex_down(&block->lock);
if (!--block->refcnt) {
/*
* Last reference to the block was dropped, put the block on the
* free list.
*/
list_append(&block->free_link, &cache->free_head);
}
futex_up(&block->lock);
futex_up(&cache->lock);
}
 
/** Read data from a block device.
*
* @param dev_handle Device handle of the block device.
443,9 → 211,9
* @param size Size of the destination buffer.
* @param block_size Block size to be used for the transfer.
*
* @return EOK on success or a negative return code on failure.
* @return True on success, false on failure.
*/
int
bool
block_read(int dev_handle, off_t *bufpos, size_t *buflen, off_t *pos, void *dst,
size_t size, size_t block_size)
{
480,7 → 248,7
int rc = async_req_2_1(devcon->dev_phone, RD_READ_BLOCK,
*pos / block_size, block_size, &retval);
if ((rc != EOK) || (retval != EOK))
return (rc != EOK ? rc : retval);
return false;
*bufpos = 0;
*buflen = block_size;
487,8 → 255,44
}
}
return EOK;
return true;
}
 
block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs)
{
/* FIXME */
block_t *b;
off_t bufpos = 0;
size_t buflen = 0;
off_t pos = offset * bs;
 
b = malloc(sizeof(block_t));
if (!b)
return NULL;
b->data = malloc(bs);
if (!b->data) {
free(b);
return NULL;
}
b->size = bs;
 
if (!block_read(dev_handle, &bufpos, &buflen, &pos, b->data,
bs, bs)) {
free(b->data);
free(b);
return NULL;
}
 
return b;
}
 
void block_put(block_t *block)
{
/* FIXME */
free(block->data);
free(block);
}
 
/** @}
*/
/branches/tracing/uspace/lib/libblock/libblock.h
44,24 → 44,6
#include <libadt/hash_table.h>
#include <libadt/list.h>
 
/*
* Flags that can be used with block_get().
*/
 
/**
* This macro is a symbolic value for situations where no special flags are
* needed.
*/
#define BLOCK_FLAGS_NONE 0
 
/**
* When the client of block_get() intends to overwrite the current contents of
* the block, this flag is used to avoid the unnecessary read.
*/
#define BLOCK_FLAGS_NOREAD 1
 
typedef unsigned bn_t; /**< Block number type. */
 
typedef struct block {
/** Futex protecting the reference count. */
futex_t lock;
74,7 → 56,7
/** Handle of the device where the block resides. */
dev_handle_t dev_handle;
/** Block offset on the block device. Counted in 'size'-byte blocks. */
bn_t boff;
off_t boff;
/** Size of the block. */
size_t size;
/** Link for placing the block into the free block list. */
85,18 → 67,14
void *data;
} block_t;
 
extern int block_init(dev_handle_t, size_t);
extern int block_init(dev_handle_t, size_t, off_t, size_t);
extern void block_fini(dev_handle_t);
 
extern int block_bb_read(dev_handle_t, off_t, size_t);
extern void *block_bb_get(dev_handle_t);
 
extern int block_cache_init(dev_handle_t, size_t, unsigned);
 
extern block_t *block_get(dev_handle_t, bn_t, int flags);
extern block_t *block_get(dev_handle_t, off_t, size_t);
extern void block_put(block_t *);
 
extern int block_read(int, off_t *, size_t *, off_t *, void *, size_t, size_t);
extern bool block_read(int, off_t *, size_t *, off_t *, void *, size_t, size_t);
 
#endif
 
/branches/tracing/uspace/lib/libblock/Makefile
30,8 → 30,6
## Common compiler flags
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../libc
## Setup toolchain
#
/branches/tracing/uspace/lib/softint/Makefile
29,8 → 29,6
## Common compiler flags
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../libc
## Setup toolchain
#
/branches/tracing/uspace/lib/libc/include/loader/loader.h
44,7 → 44,7
int phone_id;
} loader_t;
 
extern loader_t *loader_spawn(char *name);
extern loader_t *loader_spawn(void);
extern int loader_get_task_id(loader_t *, task_id_t *);
extern int loader_set_pathname(loader_t *, const char *);
extern int loader_set_args(loader_t *, char *const []);
/branches/tracing/uspace/lib/libc/generic/loader.c
46,11 → 46,10
/** Connect to a new program loader.
*
* Spawns a new program loader task and returns the connection structure.
* @param name Symbolic name to set on the newly created task.
* @return Pointer to the loader connection structure (should be
* de-allocated using free() after use).
*/
loader_t *loader_spawn(char *name)
loader_t *loader_spawn(void)
{
int phone_id, rc;
loader_t *ldr;
58,8 → 57,7
/*
* Ask kernel to spawn a new loader task.
*/
rc = __SYSCALL3(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id,
(sysarg_t) name, strlen(name));
rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
if (rc != 0)
return NULL;
 
/branches/tracing/uspace/lib/libc/generic/task.c
64,7 → 64,7
int rc;
 
/* Spawn a program loader. */
ldr = loader_spawn(path);
ldr = loader_spawn();
if (ldr == NULL)
return 0;
 
/branches/tracing/uspace/lib/libc/generic/thread.c
108,8 → 108,8
uarg->uspace_thread_arg = arg;
uarg->uspace_uarg = uarg;
rc = __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name,
(sysarg_t) strlen(name), (sysarg_t) tid);
rc = __SYSCALL3(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name,
(sysarg_t) tid);
if (rc) {
/*
/branches/tracing/uspace/lib/libc/Makefile
29,8 → 29,6
## Common compiler flags
#
 
include ../../Makefile.config
 
LIBC_PREFIX = $(shell pwd)
SOFTINT_PREFIX = ../softint
CONSOLE_PREFIX = ../../srv/console
/branches/tracing/uspace/lib/libc/arch/ppc32/src/entry.s
34,12 → 34,11
 
## User-space task entry point
#
# r6 contains the PCB pointer
# r3 contains the PCB pointer
#
__entry:
# Pass the PCB pointer to __main() as the first argument.
# The first argument is passed in r3.
mr %r3, %r6
# Since the first argument is passed in r3, no operation is needed.
bl __main
 
bl __exit
/branches/tracing/uspace/srv/loader/main.c
247,7 → 247,7
if (prog_info.interp == NULL) {
/* Statically linked program */
// printf("Run statically linked program\n");
// printf("entry point: 0x%lx\n", prog_info.entry);
// printf("entry point: 0x%llx\n", prog_info.entry);
is_dyn_linked = false;
ipc_answer_0(rid, EOK);
return 0;
285,7 → 285,7
if (is_dyn_linked == true) {
/* Dynamically linked program */
printf("run dynamic linker\n");
printf("entry point: 0x%lx\n", interp_info.entry);
printf("entry point: 0x%llx\n", interp_info.entry);
close_console();
 
ipc_answer_0(rid, EOK);
319,8 → 319,6
callid = async_get_call(&call);
 
switch (IPC_GET_METHOD(call)) {
case IPC_M_PHONE_HUNGUP:
exit(0);
case LOADER_GET_TASKID:
loader_get_taskid(callid, &call);
continue;
/branches/tracing/uspace/srv/loader/Makefile
27,6 → 27,7
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
include ../../../version
include ../../Makefile.config
 
## Setup toolchain
/branches/tracing/uspace/srv/loader/arch/ppc32/ppc32.s
36,5 → 36,5
# Jump to a program entry point
program_run:
mtctr %r3
mr %r6, %r4 # Pass pcb to the entry point in %r6
mr %r3, %r4 # Pass pcb to the entry point in %r3
bctr
/branches/tracing/uspace/srv/fs/tmpfs/tmpfs_dump.c
65,8 → 65,8
tmpfs_dentry_t *node;
uint32_t size;
if (block_read(dev, bufpos, buflen, pos, &entry, sizeof(entry),
TMPFS_BLOCK_SIZE) != EOK)
if (!block_read(dev, bufpos, buflen, pos, &entry, sizeof(entry),
TMPFS_BLOCK_SIZE))
return false;
entry.len = uint32_t_le2host(entry.len);
79,14 → 79,14
if (fname == NULL)
return false;
node = (tmpfs_dentry_t *) ops->create(dev, L_FILE);
node = (tmpfs_dentry_t *) ops->create(L_FILE);
if (node == NULL) {
free(fname);
return false;
}
if (block_read(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE) != EOK) {
if (!block_read(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE)) {
ops->destroy((void *) node);
free(fname);
return false;
100,8 → 100,8
}
free(fname);
if (block_read(dev, bufpos, buflen, pos, &size,
sizeof(size), TMPFS_BLOCK_SIZE) != EOK)
if (!block_read(dev, bufpos, buflen, pos, &size,
sizeof(size), TMPFS_BLOCK_SIZE))
return false;
size = uint32_t_le2host(size);
111,8 → 111,8
return false;
node->size = size;
if (block_read(dev, bufpos, buflen, pos, node->data,
size, TMPFS_BLOCK_SIZE) != EOK)
if (!block_read(dev, bufpos, buflen, pos, node->data,
size, TMPFS_BLOCK_SIZE))
return false;
break;
121,14 → 121,14
if (fname == NULL)
return false;
node = (tmpfs_dentry_t *) ops->create(dev, L_DIRECTORY);
node = (tmpfs_dentry_t *) ops->create(L_DIRECTORY);
if (node == NULL) {
free(fname);
return false;
}
if (block_read(dev, bufpos, buflen, pos, fname,
entry.len, TMPFS_BLOCK_SIZE) != EOK) {
if (!block_read(dev, bufpos, buflen, pos,
fname, entry.len, TMPFS_BLOCK_SIZE)) {
ops->destroy((void *) node);
free(fname);
return false;
160,7 → 160,7
libfs_ops_t *ops = &tmpfs_libfs_ops;
int rc;
 
rc = block_init(dev, TMPFS_BLOCK_SIZE);
rc = block_init(dev, TMPFS_BLOCK_SIZE, 0, 0);
if (rc != EOK)
return false;
169,8 → 169,8
off_t pos = 0;
char tag[6];
if (block_read(dev, &bufpos, &buflen, &pos, tag, 5,
TMPFS_BLOCK_SIZE) != EOK)
if (!block_read(dev, &bufpos, &buflen, &pos, tag, 5,
TMPFS_BLOCK_SIZE))
goto error;
tag[5] = 0;
/branches/tracing/uspace/srv/fs/tmpfs/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../../Makefile.config
 
LIBC_PREFIX = ../../../lib/libc
LIBFS_PREFIX = ../../../lib/libfs
LIBBLOCK_PREFIX = ../../../lib/libblock
/branches/tracing/uspace/srv/fs/tmpfs/tmpfs_ops.c
64,8 → 64,6
*/
static tmpfs_dentry_t *root;
 
#define TMPFS_DEV 0 /**< Dummy device handle for TMPFS */
 
/*
* Implementation of the libfs interface.
*/
74,7 → 72,7
static void *tmpfs_match(void *, const char *);
static void *tmpfs_node_get(dev_handle_t, fs_index_t);
static void tmpfs_node_put(void *);
static void *tmpfs_create_node(dev_handle_t, int);
static void *tmpfs_create_node(int);
static bool tmpfs_link_node(void *, void *, const char *);
static int tmpfs_unlink_node(void *, void *);
static int tmpfs_destroy_node(void *);
230,7 → 228,7
{
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
return false;
root = (tmpfs_dentry_t *) tmpfs_create_node(TMPFS_DEV, L_DIRECTORY);
root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
if (!root) {
hash_table_destroy(&dentries);
return false;
284,7 → 282,7
/* nothing to do */
}
 
void *tmpfs_create_node(dev_handle_t dev_handle, int lflag)
void *tmpfs_create_node(int lflag)
{
assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
 
/branches/tracing/uspace/srv/fs/fat/fat.h
202,7 → 202,6
extern void fat_lookup(ipc_callid_t, ipc_call_t *);
extern void fat_read(ipc_callid_t, ipc_call_t *);
extern void fat_write(ipc_callid_t, ipc_call_t *);
extern void fat_truncate(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);
/branches/tracing/uspace/srv/fs/fat/fat_fat.c
54,109 → 54,125
*/
static futex_t fat_alloc_lock = FUTEX_INITIALIZER;
 
/** Walk the cluster chain.
/** Read block from file located on a FAT file system.
*
* @param bs Buffer holding the boot sector for the file.
* @param dev_handle Device handle of the device with the file.
* @param firstc First cluster to start the walk with.
* @param lastc If non-NULL, output argument hodling the last cluster number visited.
* @param max_clusters Maximum number of clusters to visit.
* @param bs Buffer holding the boot sector of the file system.
* @param dev_handle Device handle of the file system.
* @param firstc First cluster used by the file. Can be zero if the file
* is empty.
* @param offset Offset in blocks.
*
* @return Number of clusters seen during the walk.
* @return Block structure holding the requested block.
*/
uint16_t
fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
fat_cluster_t *lastc, uint16_t max_clusters)
block_t *
_fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
off_t offset)
{
block_t *b;
unsigned bps;
unsigned spc;
unsigned rscnt; /* block address of the first FAT */
uint16_t clusters = 0;
unsigned fatcnt;
unsigned rde;
unsigned rds; /* root directory size */
unsigned sf;
unsigned ssa; /* size of the system area */
unsigned clusters;
fat_cluster_t clst = firstc;
unsigned i;
 
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
rscnt = uint16_t_le2host(bs->rscnt);
fatcnt = bs->fatcnt;
rde = uint16_t_le2host(bs->root_ent_max);
sf = uint16_t_le2host(bs->sec_per_fat);
 
if (firstc == FAT_CLST_RES0) {
/* No space allocated to the file. */
if (lastc)
*lastc = firstc;
return 0;
rds = (sizeof(fat_dentry_t) * rde) / bps;
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
ssa = rscnt + fatcnt * sf + rds;
 
if (firstc == FAT_CLST_ROOT) {
/* root directory special case */
assert(offset < rds);
b = block_get(dev_handle, rscnt + fatcnt * sf + offset, bps);
return b;
}
 
while (clst < FAT_CLST_LAST1 && clusters < max_clusters) {
bn_t fsec; /* sector offset relative to FAT1 */
clusters = offset / spc;
for (i = 0; i < clusters; i++) {
unsigned fsec; /* sector offset relative to FAT1 */
unsigned fidx; /* FAT1 entry index */
 
assert(clst >= FAT_CLST_FIRST);
if (lastc)
*lastc = clst; /* remember the last cluster number */
assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);
fsec = (clst * sizeof(fat_cluster_t)) / bps;
fidx = clst % (bps / sizeof(fat_cluster_t));
/* read FAT1 */
b = block_get(dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE);
b = block_get(dev_handle, rscnt + fsec, bps);
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
assert(clst != FAT_CLST_BAD);
assert(clst < FAT_CLST_LAST1);
block_put(b);
clusters++;
}
 
if (lastc && clst < FAT_CLST_LAST1)
*lastc = clst;
b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +
offset % spc, bps);
 
return clusters;
return b;
}
 
/** Read block from file located on a FAT file system.
/** Return number of blocks allocated to a file.
*
* @param bs Buffer holding the boot sector of the file system.
* @param dev_handle Device handle of the file system.
* @param firstc First cluster used by the file. Can be zero if the file
* is empty.
* @param bn Block number.
* @param flags Flags passed to libblock.
* @param bs Buffer holding the boot sector for the file.
* @param dev_handle Device handle of the device with the file.
* @param firstc First cluster of the file.
* @param lastc If non-NULL, output argument holding the
* last cluster.
*
* @return Block structure holding the requested block.
* @return Number of blocks allocated to the file.
*/
block_t *
_fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
bn_t bn, int flags)
uint16_t
_fat_blcks_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
fat_cluster_t *lastc)
{
block_t *b;
unsigned bps;
unsigned spc;
unsigned rscnt; /* block address of the first FAT */
unsigned rde;
unsigned rds; /* root directory size */
unsigned sf;
unsigned ssa; /* size of the system area */
unsigned clusters, max_clusters;
fat_cluster_t lastc;
unsigned clusters = 0;
fat_cluster_t clst = firstc;
 
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
rscnt = uint16_t_le2host(bs->rscnt);
rde = uint16_t_le2host(bs->root_ent_max);
sf = uint16_t_le2host(bs->sec_per_fat);
 
rds = (sizeof(fat_dentry_t) * rde) / bps;
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
ssa = rscnt + bs->fatcnt * sf + rds;
 
if (firstc == FAT_CLST_ROOT) {
/* root directory special case */
assert(bn < rds);
b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn, flags);
return b;
if (firstc == FAT_CLST_RES0) {
/* No space allocated to the file. */
if (lastc)
*lastc = firstc;
return 0;
}
 
max_clusters = bn / bs->spc;
clusters = fat_cluster_walk(bs, dev_handle, firstc, &lastc,
max_clusters);
assert(clusters == max_clusters);
while (clst < FAT_CLST_LAST1) {
unsigned fsec; /* sector offset relative to FAT1 */
unsigned fidx; /* FAT1 entry index */
 
b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc +
bn % bs->spc, flags);
assert(clst >= FAT_CLST_FIRST);
if (lastc)
*lastc = clst; /* remember the last cluster */
fsec = (clst * sizeof(fat_cluster_t)) / bps;
fidx = clst % (bps / sizeof(fat_cluster_t));
/* read FAT1 */
b = block_get(dev_handle, rscnt + fsec, bps);
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
assert(clst != FAT_CLST_BAD);
block_put(b);
clusters++;
}
 
return b;
if (lastc)
*lastc = clst;
return clusters * spc;
}
 
/** Fill the gap between EOF and a new file position.
184,9 → 200,7
/* zero out already allocated space */
for (o = nodep->size - 1; o < pos && o < boundary;
o = ALIGN_DOWN(o + bps, bps)) {
int flags = (o % bps == 0) ?
BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE;
b = fat_block_get(bs, nodep, o / bps, flags);
b = fat_block_get(bs, nodep, o / bps);
memset(b->data + o % bps, 0, bps - o % bps);
b->dirty = true; /* need to sync node */
block_put(b);
198,7 → 212,7
/* zero out the initial part of the new cluster chain */
for (o = boundary; o < pos; o += bps) {
b = _fat_block_get(bs, nodep->idx->dev_handle, mcl,
(o - boundary) / bps, BLOCK_FLAGS_NOREAD);
(o - boundary) / bps);
memset(b->data, 0, min(bps, pos - o));
b->dirty = true; /* need to sync node */
block_put(b);
205,44 → 219,16
}
}
 
/** Get cluster from the first FAT.
/** Mark cluster in one instance of FAT.
*
* @param bs Buffer holding the boot sector for the file system.
* @param dev_handle Device handle for the file system.
* @param clst Cluster which to get.
*
* @return Value found in the cluster.
*/
fat_cluster_t
fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst)
{
block_t *b;
uint16_t bps;
uint16_t rscnt;
fat_cluster_t *cp, value;
 
bps = uint16_t_le2host(bs->bps);
rscnt = uint16_t_le2host(bs->rscnt);
 
b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps,
BLOCK_FLAGS_NONE);
cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
value = uint16_t_le2host(*cp);
block_put(b);
return value;
}
 
/** Set cluster in one instance of FAT.
*
* @param bs Buffer holding the boot sector for the file system.
* @param dev_handle Device handle for the file system.
* @param fatno Number of the FAT instance where to make the change.
* @param clst Cluster which is to be set.
* @param value Value to set the cluster with.
* @param clst Cluster which is to be marked.
* @param value Value mark the cluster with.
*/
void
fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
fat_mark_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
fat_cluster_t clst, fat_cluster_t value)
{
block_t *b;
257,7 → 243,7
 
assert(fatno < bs->fatcnt);
b = block_get(dev_handle, rscnt + sf * fatno +
(clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
(clst * sizeof(fat_cluster_t)) / bps, bps);
cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
*cp = host2uint16_t_le(value);
b->dirty = true; /* need to sync block */
279,7 → 265,7
 
for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) {
for (c = 0; c < nclsts; c++) {
fat_set_cluster(bs, dev_handle, fatno, lifo[c],
fat_mark_cluster(bs, dev_handle, fatno, lifo[c],
c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]);
}
}
327,7 → 313,7
*/
futex_down(&fat_alloc_lock);
for (b = 0, cl = 0; b < sf; blk++) {
blk = block_get(dev_handle, rscnt + b, BLOCK_FLAGS_NOREAD);
blk = block_get(dev_handle, rscnt + b, bps);
for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {
fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
if (uint16_t_le2host(*clst) == FAT_CLST_RES0) {
363,7 → 349,7
* we have allocated so far.
*/
while (found--) {
fat_set_cluster(bs, dev_handle, FAT1, lifo[found],
fat_mark_cluster(bs, dev_handle, FAT1, lifo[found],
FAT_CLST_RES0);
}
371,32 → 357,9
return ENOSPC;
}
 
/** Free clusters forming a cluster chain in all copies of FAT.
*
* @param bs Buffer hodling the boot sector of the file system.
* @param dev_handle Device handle of the file system.
* @param firstc First cluster in the chain which is to be freed.
*/
void
fat_free_clusters(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc)
{
unsigned fatno;
fat_cluster_t nextc;
 
/* Mark all clusters in the chain as free in all copies of FAT. */
while (firstc < FAT_CLST_LAST1) {
nextc = fat_get_cluster(bs, dev_handle, firstc);
assert(nextc >= FAT_CLST_FIRST && nextc < FAT_CLST_BAD);
for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
fat_set_cluster(bs, dev_handle, fatno, firstc,
FAT_CLST_RES0);
firstc = nextc;
}
}
 
/** Append a cluster chain to the last file cluster in all FATs.
*
* @param bs Buffer holding the boot sector of the file system.
* @param bs Buffer holding boot sector of the file system.
* @param nodep Node representing the file.
* @param mcl First cluster of the cluster chain to append.
*/
406,9 → 369,7
fat_cluster_t lcl;
uint8_t fatno;
 
if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl,
(uint16_t) -1) == 0) {
/* No clusters allocated to the node yet. */
if (_fat_blcks_get(bs, dev_handle, nodep->firstc, &lcl) == 0) {
nodep->firstc = host2uint16_t_le(mcl);
nodep->dirty = true; /* need to sync node */
return;
415,40 → 376,9
}
 
for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl);
fat_mark_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl);
}
 
/** Chop off node clusters in all copies of FAT.
*
* @param bs Buffer holding the boot sector of the file system.
* @param nodep FAT node where the chopping will take place.
* @param lastc Last cluster which will remain in the node. If this
* argument is FAT_CLST_RES0, then all clusters will
* be chopped off.
*/
void fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc)
{
dev_handle_t dev_handle = nodep->idx->dev_handle;
if (lastc == FAT_CLST_RES0) {
/* The node will have zero size and no clusters allocated. */
fat_free_clusters(bs, dev_handle, nodep->firstc);
nodep->firstc = FAT_CLST_RES0;
nodep->dirty = true; /* need to sync node */
} else {
fat_cluster_t nextc;
unsigned fatno;
 
nextc = fat_get_cluster(bs, dev_handle, lastc);
 
/* Terminate the cluster chain in all copies of FAT. */
for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
fat_set_cluster(bs, dev_handle, fatno, lastc, FAT_CLST_LAST1);
 
/* Free all following clusters. */
fat_free_clusters(bs, dev_handle, nextc);
}
}
 
/**
* @}
*/
/branches/tracing/uspace/srv/fs/fat/fat_fat.h
35,7 → 35,6
 
#include "../../vfs/vfs.h"
#include <stdint.h>
#include <libblock.h>
 
#define FAT1 0
 
58,28 → 57,21
 
typedef uint16_t fat_cluster_t;
 
#define fat_clusters_get(bs, dh, fc) \
fat_cluster_walk((bs), (dh), (fc), NULL, (uint16_t) -1)
extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t,
fat_cluster_t *, uint16_t);
 
#define fat_block_get(bs, np, bn, flags) \
_fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn), (flags))
 
#define fat_block_get(bs, np, off) \
_fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (off))
extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t,
fat_cluster_t, bn_t, int);
fat_cluster_t, off_t);
extern uint16_t _fat_blcks_get(struct fat_bs *, dev_handle_t, fat_cluster_t,
fat_cluster_t *);
extern void fat_append_clusters(struct fat_bs *, struct fat_node *,
fat_cluster_t);
extern void fat_chop_clusters(struct fat_bs *, struct fat_node *,
fat_cluster_t);
extern int fat_alloc_clusters(struct fat_bs *, dev_handle_t, unsigned,
fat_cluster_t *, fat_cluster_t *);
extern void fat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t);
extern void fat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t,
fat_cluster_t *, unsigned);
extern fat_cluster_t fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
extern void fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned,
extern void fat_mark_cluster(struct fat_bs *, dev_handle_t, unsigned,
fat_cluster_t, fat_cluster_t);
extern void fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,
off_t);
/branches/tracing/uspace/srv/fs/fat/fat.c
113,9 → 113,6
case VFS_WRITE:
fat_write(callid, &call);
break;
case VFS_TRUNCATE:
fat_truncate(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
/branches/tracing/uspace/srv/fs/fat/fat_ops.c
89,7 → 89,7
/* Read the block that contains the dentry of interest. */
b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc,
(node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
(node->idx->pdi * sizeof(fat_dentry_t)) / bps);
 
d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps);
 
102,42 → 102,6
block_put(b);
}
 
static fat_node_t *fat_node_get_new(void)
{
fat_node_t *nodep;
 
futex_down(&ffn_futex);
if (!list_empty(&ffn_head)) {
/* Try to use a cached free node structure. */
fat_idx_t *idxp_tmp;
nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
if (futex_trydown(&nodep->lock) == ESYNCH_WOULD_BLOCK)
goto skip_cache;
idxp_tmp = nodep->idx;
if (futex_trydown(&idxp_tmp->lock) == ESYNCH_WOULD_BLOCK) {
futex_up(&nodep->lock);
goto skip_cache;
}
list_remove(&nodep->ffn_link);
futex_up(&ffn_futex);
if (nodep->dirty)
fat_node_sync(nodep);
idxp_tmp->nodep = NULL;
futex_up(&nodep->lock);
futex_up(&idxp_tmp->lock);
} else {
skip_cache:
/* Try to allocate a new node structure. */
futex_up(&ffn_futex);
nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
if (!nodep)
return NULL;
}
fat_node_initialize(nodep);
return nodep;
}
 
/** Internal version of fat_node_get().
*
* @param idxp Locked index structure.
149,7 → 113,6
fat_dentry_t *d;
fat_node_t *nodep = NULL;
unsigned bps;
unsigned spc;
unsigned dps;
 
if (idxp->nodep) {
170,18 → 133,42
assert(idxp->pfc);
 
nodep = fat_node_get_new();
if (!nodep)
return NULL;
futex_down(&ffn_futex);
if (!list_empty(&ffn_head)) {
/* Try to use a cached free node structure. */
fat_idx_t *idxp_tmp;
nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
if (futex_trydown(&nodep->lock) == ESYNCH_WOULD_BLOCK)
goto skip_cache;
idxp_tmp = nodep->idx;
if (futex_trydown(&idxp_tmp->lock) == ESYNCH_WOULD_BLOCK) {
futex_up(&nodep->lock);
goto skip_cache;
}
list_remove(&nodep->ffn_link);
futex_up(&ffn_futex);
if (nodep->dirty)
fat_node_sync(nodep);
idxp_tmp->nodep = NULL;
futex_up(&nodep->lock);
futex_up(&idxp_tmp->lock);
} else {
skip_cache:
/* Try to allocate a new node structure. */
futex_up(&ffn_futex);
nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
if (!nodep)
return NULL;
}
fat_node_initialize(nodep);
 
bs = block_bb_get(idxp->dev_handle);
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
dps = bps / sizeof(fat_dentry_t);
 
/* Read the block that contains the dentry of interest. */
b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc,
(idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
(idxp->pdi * sizeof(fat_dentry_t)) / bps);
assert(b);
 
d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps);
197,8 → 184,8
* defined for the directory entry type. We must determine the
* size of the directory by walking the FAT.
*/
nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle,
uint16_t_le2host(d->firstc));
nodep->size = bps * _fat_blcks_get(bs, idxp->dev_handle,
uint16_t_le2host(d->firstc), NULL);
} else {
nodep->type = FAT_FILE;
nodep->size = uint32_t_le2host(d->size);
244,7 → 231,7
futex_up(&nodep->lock);
}
 
static void *fat_create(dev_handle_t dev_handle, int flags)
static void *fat_create(int flags)
{
return NULL; /* not supported at the moment */
}
282,7 → 269,7
dps = bps / sizeof(fat_dentry_t);
blocks = parentp->size / bps;
for (i = 0; i < blocks; i++) {
b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE);
b = fat_block_get(bs, parentp, i);
for (j = 0; j < dps; j++) {
d = ((fat_dentry_t *)b->data) + j;
switch (fat_classify_dentry(d)) {
372,7 → 359,7
for (i = 0; i < blocks; i++) {
fat_dentry_t *d;
b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE);
b = fat_block_get(bs, nodep, i);
for (j = 0; j < dps; j++) {
d = ((fat_dentry_t *)b->data) + j;
switch (fat_classify_dentry(d)) {
447,20 → 434,12
int rc;
 
/* initialize libblock */
rc = block_init(dev_handle, BS_SIZE);
rc = block_init(dev_handle, BS_SIZE, BS_BLOCK * BS_SIZE, BS_SIZE);
if (rc != EOK) {
ipc_answer_0(rid, rc);
ipc_answer_0(rid, 0);
return;
}
 
/* prepare the boot block */
rc = block_bb_read(dev_handle, BS_BLOCK * BS_SIZE, BS_SIZE);
if (rc != EOK) {
block_fini(dev_handle);
ipc_answer_0(rid, rc);
return;
}
 
/* get the buffer with the boot sector */
bs = block_bb_get(dev_handle);
474,14 → 453,6
return;
}
 
/* Initialize the block cache */
rc = block_cache_init(dev_handle, bps, 0 /* XXX */);
if (rc != EOK) {
block_fini(dev_handle);
ipc_answer_0(rid, rc);
return;
}
 
rc = fat_idx_init_by_dev_handle(dev_handle);
if (rc != EOK) {
block_fini(dev_handle);
574,8 → 545,7
} else {
bytes = min(len, bps - pos % bps);
bytes = min(bytes, nodep->size - pos);
b = fat_block_get(bs, nodep, pos / bps,
BLOCK_FLAGS_NONE);
b = fat_block_get(bs, nodep, pos / bps);
(void) ipc_data_read_finalize(callid, b->data + pos % bps,
bytes);
block_put(b);
600,7 → 570,7
while (bnum < nodep->size / bps) {
off_t o;
 
b = fat_block_get(bs, nodep, bnum, BLOCK_FLAGS_NONE);
b = fat_block_get(bs, nodep, bnum);
for (o = pos % (bps / sizeof(fat_dentry_t));
o < bps / sizeof(fat_dentry_t);
o++, pos++) {
646,9 → 616,7
block_t *b;
uint16_t bps;
unsigned spc;
unsigned bpc; /* bytes per cluster */
off_t boundary;
int flags = BLOCK_FLAGS_NONE;
if (!nodep) {
ipc_answer_0(rid, ENOENT);
655,6 → 623,13
return;
}
/* XXX remove me when you are ready */
{
ipc_answer_0(rid, ENOTSUP);
fat_node_put(nodep);
return;
}
 
ipc_callid_t callid;
size_t len;
if (!ipc_data_write_receive(&callid, &len)) {
664,11 → 639,6
return;
}
 
bs = block_bb_get(dev_handle);
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
bpc = bps * spc;
 
/*
* In all scenarios, we will attempt to write out only one block worth
* of data at maximum. There might be some more efficient approaches,
677,10 → 647,12
* value signalizing a smaller number of bytes written.
*/
bytes = min(len, bps - pos % bps);
if (bytes == bps)
flags |= BLOCK_FLAGS_NOREAD;
 
bs = block_bb_get(dev_handle);
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
boundary = ROUND_UP(nodep->size, bpc);
boundary = ROUND_UP(nodep->size, bps * spc);
if (pos < boundary) {
/*
* This is the easier case - we are either overwriting already
689,7 → 661,7
* next block size boundary.
*/
fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos);
b = fat_block_get(bs, nodep, pos / bps, flags);
b = fat_block_get(bs, nodep, pos / bps);
(void) ipc_data_write_finalize(callid, b->data + pos % bps,
bytes);
b->dirty = true; /* need to sync block */
698,8 → 670,8
nodep->size = pos + bytes;
nodep->dirty = true; /* need to sync node */
}
ipc_answer_2(rid, EOK, bytes, nodep->size);
fat_node_put(nodep);
ipc_answer_1(rid, EOK, bytes);
return;
} else {
/*
708,11 → 680,13
*/
int status;
unsigned nclsts;
fat_cluster_t mcl, lcl;
nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
fat_cluster_t mcl, lcl;
nclsts = (ROUND_UP(pos + bytes, bps * spc) - boundary) /
bps * spc;
/* create an independent chain of nclsts clusters in all FATs */
status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl,
&lcl);
if (status != EOK) {
/* could not allocate a chain of nclsts clusters */
fat_node_put(nodep);
722,8 → 696,8
}
/* zero fill any gaps */
fat_fill_gap(bs, nodep, mcl, pos);
b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc,
flags);
b = _fat_block_get(bs, dev_handle, lcl,
(pos / bps) % spc);
(void) ipc_data_write_finalize(callid, b->data + pos % bps,
bytes);
b->dirty = true; /* need to sync block */
735,70 → 709,12
fat_append_clusters(bs, nodep, mcl);
nodep->size = pos + bytes;
nodep->dirty = true; /* need to sync node */
ipc_answer_2(rid, EOK, bytes, nodep->size);
fat_node_put(nodep);
ipc_answer_1(rid, EOK, bytes);
return;
}
}
 
void fat_truncate(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
size_t size = (off_t)IPC_GET_ARG3(*request);
fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
fat_bs_t *bs;
uint16_t bps;
uint8_t spc;
unsigned bpc; /* bytes per cluster */
int rc;
 
if (!nodep) {
ipc_answer_0(rid, ENOENT);
return;
}
 
bs = block_bb_get(dev_handle);
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
bpc = bps * spc;
 
if (nodep->size == size) {
rc = EOK;
} else if (nodep->size < size) {
/*
* The standard says we have the freedom to grow the node.
* For now, we simply return an error.
*/
rc = EINVAL;
} else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) {
/*
* The node will be shrunk, but no clusters will be deallocated.
*/
nodep->size = size;
nodep->dirty = true; /* need to sync node */
rc = EOK;
} else {
/*
* The node will be shrunk, clusters will be deallocated.
*/
if (size == 0) {
fat_chop_clusters(bs, nodep, FAT_CLST_RES0);
} else {
fat_cluster_t lastc;
(void) fat_cluster_walk(bs, dev_handle, nodep->firstc,
&lastc, (size - 1) / bpc);
fat_chop_clusters(bs, nodep, lastc);
}
nodep->size = size;
nodep->dirty = true; /* need to sync node */
rc = EOK;
}
fat_node_put(nodep);
ipc_answer_0(rid, rc);
return;
}
 
/**
* @}
*/
/branches/tracing/uspace/srv/fs/fat/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../../Makefile.config
 
LIBC_PREFIX = ../../../lib/libc
LIBFS_PREFIX = ../../../lib/libfs
LIBBLOCK_PREFIX = ../../../lib/libblock
/branches/tracing/uspace/srv/fs/fat/fat_idx.c
338,52 → 338,6
futex_up(&unused_futex);
}
 
static fat_idx_t *fat_idx_get_new_core(dev_handle_t dev_handle)
{
fat_idx_t *fidx;
 
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
if (!fidx)
return NULL;
if (!fat_idx_alloc(dev_handle, &fidx->index)) {
free(fidx);
return NULL;
}
link_initialize(&fidx->uph_link);
link_initialize(&fidx->uih_link);
futex_initialize(&fidx->lock, 1);
fidx->dev_handle = dev_handle;
fidx->pfc = FAT_CLST_RES0; /* no parent yet */
fidx->pdi = 0;
fidx->nodep = NULL;
 
return fidx;
}
 
fat_idx_t *fat_idx_get_new(dev_handle_t dev_handle)
{
fat_idx_t *fidx;
 
futex_down(&used_futex);
fidx = fat_idx_get_new_core(dev_handle);
if (!fidx) {
futex_up(&used_futex);
return NULL;
}
unsigned long ikey[] = {
[UIH_DH_KEY] = dev_handle,
[UIH_INDEX_KEY] = fidx->index,
};
hash_table_insert(&ui_hash, ikey, &fidx->uih_link);
futex_down(&fidx->lock);
futex_up(&used_futex);
 
return fidx;
}
 
fat_idx_t *
fat_idx_get_by_pos(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi)
{
400,11 → 354,16
if (l) {
fidx = hash_table_get_instance(l, fat_idx_t, uph_link);
} else {
fidx = fat_idx_get_new_core(dev_handle);
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
if (!fidx) {
futex_up(&used_futex);
return NULL;
}
if (!fat_idx_alloc(dev_handle, &fidx->index)) {
free(fidx);
futex_up(&used_futex);
return NULL;
}
unsigned long ikey[] = {
[UIH_DH_KEY] = dev_handle,
411,8 → 370,13
[UIH_INDEX_KEY] = fidx->index,
};
link_initialize(&fidx->uph_link);
link_initialize(&fidx->uih_link);
futex_initialize(&fidx->lock, 1);
fidx->dev_handle = dev_handle;
fidx->pfc = pfc;
fidx->pdi = pdi;
fidx->nodep = NULL;
 
hash_table_insert(&up_hash, pkey, &fidx->uph_link);
hash_table_insert(&ui_hash, ikey, &fidx->uih_link);
/branches/tracing/uspace/srv/vfs/Makefile
30,8 → 30,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/srv/kbd/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/srv/ns/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/srv/console/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/srv/rd/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/srv/fb/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/srv/devmap/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/srv/pci/Makefile
29,8 → 29,6
## Setup toolchain
#
 
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
/branches/tracing/uspace/Makefile
93,7 → 93,7
-rm Makefile.config
 
$(CLEANS):
-$(MAKE) -C $(basename $@) clean
-$(MAKE) -C $(basename $@) clean ARCH=$(ARCH)
 
$(BUILDS):
$(MAKE) -C $(basename $@) all
$(MAKE) -C $(basename $@) all ARCH=$(ARCH) COMPILER=$(COMPILER)
/branches/tracing/boot/arch/ia64/loader/Makefile
88,8 → 88,6
boot.S
 
COMPONENTS = \
$(KERNELDIR)/kernel.bin
NOCOMPONENTS = \
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \
/branches/tracing/boot/arch/ia64/loader/gefi/apps/Makefile
28,7 → 28,7
CRTOBJS = ../gnuefi/crt0-efi-$(ARCH).o
LDSCRIPT = ../gnuefi/elf_$(ARCH)_efi.lds
LDFLAGS += -T $(LDSCRIPT) -shared -Bsymbolic -L../lib -L../gnuefi $(CRTOBJS)
LOADLIBES = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)
LOADLIBES = -lefi -lgnuefi
FORMAT = efi-app-$(ARCH)
 
TARGETS = t.efi t2.efi t3.efi t4.efi t5.efi t6.efi printenv.efi t7.efi
/branches/tracing/boot/arch/ia64/loader/gefi/HelenOS/Makefile
28,7 → 28,7
CRTOBJS = ../gnuefi/crt0-efi-$(ARCH).o
LDSCRIPT = ../gnuefi/elf_$(ARCH)_efi.lds
LDFLAGS += -T $(LDSCRIPT) -shared -Bsymbolic -L../lib -L../gnuefi $(CRTOBJS)
LOADLIBES = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)
LOADLIBES = -lefi -lgnuefi
FORMAT = efi-app-$(ARCH)
 
 
45,29 → 45,16
-j .rela -j .reloc --target=$(FORMAT) hello.so hello.efi
$(OBJDUMP) -d hello.efi > hello.disass
 
#When selected first lines or second lines, select if image is linked into hello or not - usefull for network boot
#hello.so: hello.o image.o
hello.so: hello.o image.bin
# $(LD) $(LDFLAGS) -Map hello.map hello.o image.o -o hello.so $(LOADLIBES) #link image inside hello
$(LD) $(LDFLAGS) -Map hello.map hello.o -o hello.so $(LOADLIBES) #dont link image inside hello
hello.so: hello.o image.o
$(LD) $(LDFLAGS) -Map hello.map hello.o -o hello.so $(LOADLIBES)
 
hello.o: hello.c
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c hello.c -o hello.o
 
 
image.bin: ../../image.boot
image.o: ../../image.boot
$(OBJCOPY) -O binary ../../image.boot image.bin
$(OBJCOPY) -I binary -O elf64-ia64-little -B ia64 image.bin image.o
 
 
image.o: ../../image.boot mkimage
$(OBJCOPY) -O binary ../../image.boot image.bin
./mkimage
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c image.c -o image.o
# $(OBJCOPY) -I binary -O elf64-ia64-little -B ia64 image.bin image.o
 
mkimage: mkimage.c
gcc -o mkimage mkimage.c
 
 
gefi:
make -C .. prefix=$(PREFIX)
/branches/tracing/boot/arch/ia64/loader/gefi/HelenOS/hello.c
1,23 → 1,9
#include <efi.h>
#include <efilib.h>
 
#include <../../../../../../kernel/arch/ia64/include/bootinfo.h>
 
#define KERNEL_LOAD_ADDRESS 0x4400000
 
//Link image as a data array into hello - usefull with network boot
//#define IMAGE_LINKED
 
bootinfo_t *bootinfo=(bootinfo_t *)BOOTINFO_ADDRESS;
 
 
#ifdef IMAGE_LINKED
extern char HOSimage[];
extern int HOSimagesize;
#endif
 
 
 
static CHAR16 *
a2u (char *str)
{
29,7 → 15,24
mem[i] = 0;
return mem;
}
char HEX[256];
 
char hexs[]="0123456789ABCDEF";
/*
void to_hex(unsigned long long num)
{
int a;
for(a=15;a>=0;a--)
{
char c=num - (num & 0xfffffffffffffff0LL);
num/=16;
c=hexs[c];
HEX[a]=c;
}
 
}
*/
 
EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
69,12 → 72,11
EFI_FILE *FileHandle;
 
BS->HandleProtocol(LoadedImage->DeviceHandle, &FileSystemProtocol, &Vol);
Vol->OpenVolume (Vol, &CurDir);
 
char FileName[1024];
char *OsKernelBuffer;
int i;
int defaultLoad;
int imageLoad;
UINTN Size;
 
StrCpy(FileName,DevicePathToStr(LoadedImage->FilePath));
95,10 → 97,8
}
while(LoadOptions[i]==L' ') if(LoadOptions[i++]==0) break;
if(LoadOptions[i++]==0){
if(LoadOptions[i++]==0)
StrCat(FileName,L"\\image.bin");
defaultLoad=1;
}
else{
CHAR16 buf[1024];
buf[0]='\\';
108,84 → 108,28
buf[j+1]=LoadOptions[i+j];
buf[j+1]=0;
StrCat(FileName,buf);
defaultLoad=0;
}
//Print(L"%s\n",FileName);
 
imageLoad=1;
#ifdef IMAGE_LINKED
if(defaultLoad) {
Print(L"Using Linked Image\n");
imageLoad=0;
EFI_STATUS stat;
stat=CurDir->Open(CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
if(EFI_ERROR(stat)){
Print(L"Error Opening Image %s\n",FileName);
return 0;
}
#endif
Size = 0x00400000;
BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer);
FileHandle->Read(FileHandle, &Size, OsKernelBuffer);
FileHandle->Close(FileHandle);
 
char * HOS;
if(imageLoad)
{
Size = 0x00400000;
if(Size<1) return 0;
 
Vol->OpenVolume (Vol, &CurDir);
 
EFI_STATUS stat;
stat=CurDir->Open(CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
if(EFI_ERROR(stat)){
Print(L"Error Opening Image %s\n",FileName);
return 0;
}
BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer);
FileHandle->Read(FileHandle, &Size, OsKernelBuffer);
FileHandle->Close(FileHandle);
HOS = OsKernelBuffer;
if(Size<1) return 0;
 
}
#ifdef IMAGE_LINKED
else {
HOS = HOSimage;
Size = HOSimagesize;
Print(L"Image start %llX\n",(long long)HOS);
Print(L"Image size %llX\n",(long long)Size);
Print(L"Image &size %llX\n",(long long)&Size);
}
#endif
char * HOS = OsKernelBuffer;
int HOSSize = Size;
 
 
rArg rSAL;
rArg rPAL;
 
//Setup AP's wake up address
LibSalProc(0x01000000,2,0x4400200,0,0,0,0,0,&rSAL);
 
 
//Get System Frequency
UINT64 sys_freq;
LibSalProc(0x01000012,0,0,0,0,0,0,0,&rSAL);
sys_freq=rSAL.p1;
 
UINT64 freq_scale;
//Get CPU Frequency to System Frequency ratio
LibPalProc(14,0,0,0,&rPAL);
freq_scale=rPAL.p1;
 
 
UINT64 sapic;
LibGetSalIpiBlock(&sapic);
Print (L"SAPIC:%X\n", sapic);
//bootinfo->sapic=sapic;
 
 
int wakeup_intno;
wakeup_intno=0xf0;
Print (L"WAKEUP INTNO:%X\n", wakeup_intno);
//bootinfo->wakeup_intno=wakeup_intno;
 
 
 
 
 
{
UINTN cookie;
void *p=(void *)KERNEL_LOAD_ADDRESS;
223,10 → 167,6
for(a=0;a<HOSSize;a++){
((char *)(0x4400000))[a]=HOS[a];
}
bootinfo->sapic=(unsigned long *)sapic;
bootinfo->wakeup_intno=wakeup_intno;
bootinfo->sys_freq=sys_freq;
bootinfo->freq_scale=freq_scale;
//Run Kernel
asm volatile(
237,6 → 177,8
);
//Not reached
while(1){
((volatile int *)(0x80000000000b8000))[0]++;
}
return EFI_SUCCESS;
}
/branches/tracing/boot/arch/ia64/loader/boot.S
34,7 → 34,6
.global start
start:
 
 
mov ar.rsc = r0
# movl r8 = (VRN_KERNEL << VRN_SHIFT) ;;
movl r1 = 0x4400000
58,22 → 57,6
mov b1 = r18 ;;
br.call.sptk.many b0 = b1
 
.align 512
ap_start:
 
 
ap_loop:
movl r18=0x4405000;;
mov b1 = r18 ;;
br.call.sptk.many b0 = b1;;
 
.align 1024
 
.align 4096
.global binfo
binfo:
 
 
.bss #on this line is ".bss", it cannot be seen in my mcedit :-(
 
 
/branches/tracing/boot/arch/ia64/loader/asm.S
37,5 → 37,7
alloc loc0 = ar.pfs, 1, 1, 0, 0
movl r8 = 0x4404000;;
mov b1 = r8 ;;
mov r1 = in0; #Save bootinfo prt
mov r1 = in0;
br.call.sptk.many b0 = b1;;
.global ofw
ofw:
/branches/tracing/boot/arch/ia64/loader/main.c
34,7 → 34,7
#include <align.h>
#include <balloc.h>
 
extern bootinfo_t binfo;
bootinfo_t bootinfo;
component_t components[COMPONENTS];
 
char *release = RELEASE;
69,8 → 69,6
int ii;
bootinfo_t *bootinfo=&binfo;
//for(ii=0;ii<KERNEL_SIZE;ii++) ((char *)(0x100000))[ii] = ((char *)KERNEL_START)[ii+1];
94,18 → 92,19
components[i].name, components[i].size);
 
 
bootinfo->taskmap.count = 0;
bootinfo.taskmap.count = 0;
for (i = 0; i < COMPONENTS; i++) {
 
if (i > 0) {
bootinfo->taskmap.tasks[bootinfo->taskmap.count].addr = components[i].start;
bootinfo->taskmap.tasks[bootinfo->taskmap.count].size = components[i].size;
bootinfo->taskmap.count++;
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = components[i].start;
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size;
bootinfo.taskmap.count++;
}
}
 
jump_to_kernel(bootinfo);
 
jump_to_kernel(&bootinfo);
 
 
}
 
/branches/tracing/boot/arch/ia64/loader/main.h
29,14 → 29,29
#ifndef BOOT_ia64_MAIN_H_
#define BOOT_ia64_MAIN_H_
 
#include <ofw.h>
#include <ofw_tree.h>
#include <types.h>
#include <../../../../kernel/arch/ia64/include/bootinfo.h>
 
 
#define CONFIG_INIT_TASKS 32
 
typedef struct {
void *addr;
size_t size;
} init_task_t;
typedef struct {
count_t count;
init_task_t tasks[CONFIG_INIT_TASKS];
} init_t;
 
typedef struct {
init_t taskmap;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
 
extern void start(void);
extern void bootstrap(void);