Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3587 → Rev 3588

/branches/dynload/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] CONFIG_SMP (y/n)
! [ARCH=ia32|ARCH=amd64|ARCH=ia32xen|ARCH=sparc64|ARCH=ia64] CONFIG_SMP (y/n)
 
# Improved support for hyperthreading
! [(ARCH=ia32|ARCH=amd64|ARCH=ia32xen)&CONFIG_SMP=y] CONFIG_HT (y/n)
139,8 → 139,9
! [ARCH=sparc64] CONFIG_Z8530 (y/n)
 
# Support for NS16550 serial port
! [ARCH=sparc64] CONFIG_NS16550 (y/n)
! [ARCH=sparc64|ARCH=ia64] CONFIG_NS16550 (y/n)
 
 
# Virtually indexed D-cache support
! [ARCH=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
 
/branches/dynload/kernel/genarch/include/kbd/ns16550.h
48,7 → 48,75
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/dynload/kernel/genarch/src/kbd/ns16550.c
38,8 → 38,10
#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>
109,13 → 111,13
* @param inr Interrupt number.
* @param vaddr Virtual address of device's registers.
*/
void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr)
void ns16550_init(devno_t devno, inr_t inr, ioport_t port)
{
chardev_initialize("ns16550_kbd", &kbrd, &ops);
stdin = &kbrd;
ns16550.devno = devno;
ns16550.reg = (uint8_t *) vaddr;
ns16550.io_port = port;
irq_initialize(&ns16550_irq);
ns16550_irq.devno = devno;
125,10 → 127,21
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, vaddr);
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
ns16550_grab();
}
152,6 → 165,7
{
}
 
 
char ns16550_key_read(chardev_t *d)
{
char ch;
161,6 → 175,7
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);
167,6 → 182,15
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;
}
201,6 → 225,7
uint8_t x;
x = ns16550_rbr_read(&ns16550);
#ifndef ia64
if (x != IGNORE_CODE) {
if (x & KEY_RELEASE)
key_released(x ^ KEY_RELEASE);
207,6 → 232,15
else
key_pressed(x);
}
#else
extern chardev_t kbrd;
if(x != 0x0d) {
if (x == 0x7f)
x = '\b';
chardev_push_character(&kbrd, x);
}
#endif
 
}
}
 
/branches/dynload/kernel/genarch/src/kbd/key.c
39,9 → 39,13
#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/dynload/kernel/generic/include/synch/spinlock.h
36,6 → 36,7
#define KERN_SPINLOCK_H_
 
#include <arch/types.h>
#include <arch/barrier.h>
#include <preemption.h>
#include <atomic.h>
#include <debug.h>
/branches/dynload/kernel/generic/src/main/main.c
328,6 → 328,7
* 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/dynload/kernel/generic/src/mm/tlb.c
134,7 → 134,9
 
void tlb_shootdown_ipi_send(void)
{
#ifndef ia64
ipi_broadcast(VECTOR_TLB_SHOOTDOWN_IPI);
#endif
}
 
/** Receive TLB shootdown message. */
/branches/dynload/kernel/arch/sparc64/include/types.h
54,6 → 54,8
 
typedef uint64_t ipl_t;
 
typedef uint64_t ioport_t;
 
typedef uint64_t unative_t;
typedef int64_t native_t;
 
/branches/dynload/kernel/arch/sparc64/include/asm.h
42,7 → 42,56
#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/dynload/kernel/arch/sparc64/include/drivers/ns16550.h
35,67 → 35,7
#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/dynload/kernel/arch/sparc64/src/drivers/kbd.c
147,7 → 147,7
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_init(devno, inr, vaddr);
ns16550_init(devno, inr, (ioport_t)vaddr);
break;
#endif
default:
/branches/dynload/kernel/arch/ia64/include/atomic.h
51,6 → 51,20
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/dynload/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,6 → 46,12
 
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/dynload/kernel/arch/ia64/include/asm.h
39,10 → 39,11
#include <arch/types.h>
#include <arch/register.h>
 
typedef uint64_t ioport_t;
 
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL
 
static inline void outb(uint64_t port,uint8_t v)
static inline void outb(ioport_t port,uint8_t v)
{
*((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
49,7 → 50,7
asm volatile ("mf\n" ::: "memory");
}
 
static inline void outw(uint64_t port,uint16_t v)
static inline void outw(ioport_t port,uint16_t v)
{
*((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
56,7 → 57,7
asm volatile ("mf\n" ::: "memory");
}
 
static inline void outl(uint64_t port,uint32_t v)
static inline void outl(ioport_t port,uint32_t v)
{
*((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
 
65,7 → 66,7
 
 
 
static inline uint8_t inb(uint64_t port)
static inline uint8_t inb(ioport_t port)
{
asm volatile ("mf\n" ::: "memory");
 
72,7 → 73,7
return *((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
}
 
static inline uint16_t inw(uint64_t port)
static inline uint16_t inw(ioport_t port)
{
asm volatile ("mf\n" ::: "memory");
 
79,7 → 80,7
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xffE) | ( (port >> 2) << 12 ))));
}
 
static inline uint32_t inl(uint64_t port)
static inline uint32_t inl(ioport_t port)
{
asm volatile ("mf\n" ::: "memory");
 
98,9 → 99,14
{
uint64_t v;
 
asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
//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;
return v;
//this code have the same meaning but inlines well
asm volatile ("mov %0 = r12" : "=r" (v) );
return v & (~(STACK_SIZE-1));
}
 
/** Return Processor State Register.
152,6 → 158,16
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/dynload/kernel/arch/ia64/include/mm/page.h
46,8 → 46,20
/** 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/dynload/kernel/arch/ia64/include/cpu.h
38,6 → 38,7
#include <arch/types.h>
#include <arch/register.h>
#include <arch/asm.h>
#include <arch/bootinfo.h>
 
#define FAMILY_ITANIUM 0x7
#define FAMILY_ITANIUM2 0x1f
63,6 → 64,33
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/dynload/kernel/arch/ia64/include/drivers/it.h
41,7 → 41,7
* from firmware.
*
*/
#define IT_DELTA 100000
#define IT_DELTA it_delta
 
extern void it_init(void);
 
/branches/dynload/kernel/arch/ia64/Makefile.inc
82,6 → 82,7
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)
98,3 → 99,7
BFD = binary
endif
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
 
/branches/dynload/kernel/arch/ia64/src/ia64.c
54,7 → 54,17
#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)
102,12 → 112,15
 
void arch_post_mm_init(void)
{
irq_init(INR_COUNT, INR_COUNT);
if(config.cpu_active==1)
{
irq_init(INR_COUNT, INR_COUNT);
#ifdef SKI
ski_init_console();
ski_init_console();
#else
ega_init();
ega_init();
#endif
}
it_init();
}
 
127,6 → 140,9
{
while (1) {
i8042_poll();
#ifdef CONFIG_NS16550
ns16550_poll();
#endif
thread_usleep(POLL_INTERVAL);
}
}
135,7 → 151,7
void arch_post_smp_init(void)
{
 
if (config.cpu_active == 1) {
{
/*
* Create thread that polls keyboard.
*/
153,6 → 169,10
/* 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)
164,6 → 184,7
}
}
 
 
/** Enter userspace and never return. */
void userspace(uspace_arg_t *kernel_uarg)
{
224,7 → 245,7
 
void arch_reboot(void)
{
// TODO
outb(0x64,0xfe);
while (1);
}
 
/branches/dynload/kernel/arch/ia64/src/start.S
39,12 → 39,10
#define KERNEL_TRANSLATION_D 0x0010000000000661
#define KERNEL_TRANSLATION_VIO 0x0010000000000671
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671
#define VIO_OFFSET 0x0002000000000000
#define KERNEL_TRANSLATION_FW 0x00100000F0000671
 
#define IO_OFFSET 0x0001000000000000
 
 
 
.section K_TEXT_START, "ax"
 
.global kernel_image_start
53,6 → 51,18
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
114,8 → 124,25
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
142,6 → 169,12
 
# 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
160,25 → 193,35
movl r1 = _hardcoded_load_address
/*
* Initialize hardcoded_* variables.
* Initialize hardcoded_* variables. Do only BSP
*/
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) 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
;;
st8 [r17] = r14
st8 [r18] = r15
st8 [r19] = r16
st8 [r21] = r20
(p3) st8 [r17] = r14
(p3) st8 [r18] = r15
(p3) st8 [r19] = r16
(p3) 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 ;;
188,3 → 231,46
 
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/dynload/kernel/arch/ia64/src/smp/smp.c
0,0 → 1,174
/*
* Copyright (c) 2005 Jakub Vana
* 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 ia64
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <arch/ski/ski.h>
#include <arch/drivers/it.h>
#include <arch/interrupt.h>
#include <arch/barrier.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <arch/types.h>
#include <arch/context.h>
#include <arch/stack.h>
#include <arch/mm/page.h>
#include <mm/as.h>
#include <config.h>
#include <userspace.h>
#include <console/console.h>
#include <proc/uarg.h>
#include <syscall/syscall.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#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>
 
 
 
 
 
 
#ifdef CONFIG_SMP
 
 
extern char cpu_by_id_eid_list[256][256];
 
 
static void sapic_init(void)
{
bootinfo->sapic=(unative_t *)(PA2KA((unative_t)(bootinfo->sapic))|FW_OFFSET);
}
 
 
 
static void ipi_broadcast_arch_all(int ipi )
{
int id,eid;
int myid,myeid;
myid=ia64_get_cpu_id();
myeid=ia64_get_cpu_eid();
 
printf("Not sending to ID:%d,EID:%d",myid,myeid);
for(id=0;id<256;id++)
for(eid=0;eid<256;eid++)
if((id!=myid) || (eid!=myeid))
ipi_send_ipi(id,eid,ipi);
}
 
void ipi_broadcast_arch(int ipi )
{
ipi_broadcast_arch_all(ipi);
}
 
 
void smp_init(void)
{
sapic_init();
ipi_broadcast_arch_all(bootinfo->wakeup_intno);
volatile long long brk;
for(brk=0;brk<100LL*1024LL*1024LL;brk++); //wait a while before CPUs starts
 
config.cpu_count=0;
int id,eid;
for(id=0;id<256;id++)
for(eid=0;eid<256;eid++)
if(cpu_by_id_eid_list[id][eid]==1){
config.cpu_count++;
printf("Found CPU ID:%d EDI:%d\n",id,eid);
cpu_by_id_eid_list[id][eid]=2;
 
}
}
 
 
void kmp(void *arg __attribute__((unused)))
{
int id,eid;
int myid,myeid;
myid=ia64_get_cpu_id();
myeid=ia64_get_cpu_eid();
 
for(id=0;id<256;id++)
for(eid=0;eid<256;eid++)
if((id!=myid) || (eid!=myeid))
if(cpu_by_id_eid_list[id][eid]!=0){
if(cpu_by_id_eid_list[id][eid]==1){
//config.cpu_count++;
//cpu_by_id_eid_list[id][eid]=2;
printf("Found Late CPU ID:%d EDI:%d Not added to system!!!\n",id,eid);
continue;
}
cpu_by_id_eid_list[id][eid]=3;
/*
* There may be just one AP being initialized at
* the time. After it comes completely up, it is
* supposed to wake us up.
*/
if (waitq_sleep_timeout(&ap_completion_wq, 1000000,
SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {
printf("%s: waiting for cpu ID:%d EID:%d"
"timed out\n", __FUNCTION__,
id, eid);
}
}
}
#endif
 
 
/*This is just a hack for linking with assembler - may be removed in future*/
#ifndef CONFIG_SMP
void main_ap(void);
void main_ap(void)
{
while(1);
}
 
#endif
 
/** @}
*/
 
/branches/dynload/kernel/arch/ia64/src/mm/frame.c
42,20 → 42,31
* for real ia64 systems that provide memory map.
*/
#define MEMORY_SIZE (64 * 1024 * 1024)
#define MEMORY_BASE (64 * 1024 * 1024)
#define MEMORY_BASE (0 * 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)
{
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0);
 
if(config.cpu_active==1)
{
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));
/*
* 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);
}
}
 
/** @}
/branches/dynload/kernel/arch/ia64/src/mm/page.c
47,6 → 47,7
#include <arch/asm.h>
#include <arch/barrier.h>
#include <memstr.h>
#include <align.h>
 
static void set_environment(void);
 
262,5 → 263,27
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/dynload/kernel/arch/ia64/src/drivers/it.c
46,6 → 46,16
 
#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);
55,14 → 65,25
void it_init(void)
{
cr_itv_t itv;
 
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);
 
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;
}
/* initialize Interval Timer external interrupt vector */
itv.value = itv_read();
itv.vector = INTERRUPT_TIMER;
/branches/dynload/kernel/arch/ppc32/src/asm.S
66,9 → 66,9
mr sp, r4
 
# %r3 is defined to hold pcb_ptr - set it to 0
# %r6 is defined to hold pcb_ptr - set it to 0
 
xor r3, r3, r3
xor r6, r6, r6
# jump to userspace
/branches/dynload/kernel/arch/ppc32/src/mm/tlb.c
96,7 → 96,6
return NULL;
case AS_PF_FAULT:
page_table_lock(as, lock);
printf("Page fault.\n");
*pfrc = rc;
return NULL;
default:
/branches/dynload/kernel/arch/ppc64/src/mm/page.c
103,7 → 103,6
return NULL;
case AS_PF_FAULT:
page_table_lock(as, lock);
printf("Page fault.\n");
*pfrc = rc;
return NULL;
default:
/branches/dynload/kernel/arch/mips32/src/mm/tlb.c
429,7 → 429,6
break;
case AS_PF_FAULT:
page_table_lock(AS, true);
printf("Page fault.\n");
*pfrc = AS_PF_FAULT;
return NULL;
break;
/branches/dynload/uspace/lib/libfs/libfs.c
191,7 → 191,7
}
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
nodep = ops->create(dev_handle, lflag);
else
nodep = ops->node_get(dev_handle,
index);
262,7 → 262,7
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
nodep = ops->create(dev_handle, lflag);
else
nodep = ops->node_get(dev_handle, index);
if (nodep) {
/branches/dynload/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)(int);
void * (* create)(dev_handle_t, int);
int (* destroy)(void *);
bool (* link)(void *, void *, const char *);
int (* unlink)(void *, void *);
/branches/dynload/uspace/lib/libblock/libblock.c
299,7 → 299,7
*
* @return Block structure.
*/
block_t *block_get(dev_handle_t dev_handle, off_t boff)
block_t *block_get(dev_handle_t dev_handle, bn_t boff)
{
devcon_t *devcon;
cache_t *cache;
/branches/dynload/uspace/lib/libblock/libblock.h
44,6 → 44,8
#include <libadt/hash_table.h>
#include <libadt/list.h>
 
typedef unsigned bn_t; /**< Block number type. */
 
typedef struct block {
/** Futex protecting the reference count. */
futex_t lock;
56,7 → 58,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. */
off_t boff;
bn_t boff;
/** Size of the block. */
size_t size;
/** Link for placing the block into the free block list. */
75,7 → 77,7
 
extern int block_cache_init(dev_handle_t, size_t, unsigned);
 
extern block_t *block_get(dev_handle_t, off_t);
extern block_t *block_get(dev_handle_t, bn_t);
extern void block_put(block_t *);
 
extern int block_read(int, off_t *, size_t *, off_t *, void *, size_t, size_t);
/branches/dynload/uspace/lib/libc/arch/ppc32/src/entry.s
34,11 → 34,12
 
## User-space task entry point
#
# r3 contains the PCB pointer
# r6 contains the PCB pointer
#
__entry:
# Pass the PCB pointer to __main() as the first argument.
# Since the first argument is passed in r3, no operation is needed.
# The first argument is passed in r3.
mr %r3, %r6
bl __main
 
bl __exit
/branches/dynload/uspace/srv/loader/arch/ppc32/ppc32.s
36,5 → 36,5
# Jump to a program entry point
program_run:
mtctr %r3
mr %r3, %r4 # Pass pcb to the entry point in %r3
mr %r6, %r4 # Pass pcb to the entry point in %r6
bctr
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs_dump.c
79,7 → 79,7
if (fname == NULL)
return false;
node = (tmpfs_dentry_t *) ops->create(L_FILE);
node = (tmpfs_dentry_t *) ops->create(dev, L_FILE);
if (node == NULL) {
free(fname);
return false;
121,7 → 121,7
if (fname == NULL)
return false;
node = (tmpfs_dentry_t *) ops->create(L_DIRECTORY);
node = (tmpfs_dentry_t *) ops->create(dev, L_DIRECTORY);
if (node == NULL) {
free(fname);
return false;
/branches/dynload/uspace/srv/fs/tmpfs/tmpfs_ops.c
64,6 → 64,8
*/
static tmpfs_dentry_t *root;
 
#define TMPFS_DEV 0 /**< Dummy device handle for TMPFS */
 
/*
* Implementation of the libfs interface.
*/
72,7 → 74,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(int);
static void *tmpfs_create_node(dev_handle_t, int);
static bool tmpfs_link_node(void *, void *, const char *);
static int tmpfs_unlink_node(void *, void *);
static int tmpfs_destroy_node(void *);
228,7 → 230,7
{
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
return false;
root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
root = (tmpfs_dentry_t *) tmpfs_create_node(TMPFS_DEV, L_DIRECTORY);
if (!root) {
hash_table_destroy(&dentries);
return false;
282,7 → 284,7
/* nothing to do */
}
 
void *tmpfs_create_node(int lflag)
void *tmpfs_create_node(dev_handle_t dev_handle, int lflag)
{
assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
 
/branches/dynload/uspace/srv/fs/fat/fat_idx.c
338,6 → 338,52
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)
{
354,16 → 400,11
if (l) {
fidx = hash_table_get_instance(l, fat_idx_t, uph_link);
} else {
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
fidx = fat_idx_get_new_core(dev_handle);
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,
370,13 → 411,8
[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/dynload/uspace/srv/fs/fat/fat_fat.c
59,10 → 59,7
* @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 penult If non-NULL, output argument hodling the
* the penultimate cluster visited.
* @param ult If non-NULL, output argument holding the
* ultimate cluster visited.
* @param lastc If non-NULL, output argument hodling the last cluster number visited.
* @param max_clusters Maximum number of clusters to visit.
*
* @return Number of clusters seen during the walk.
69,7 → 66,7
*/
uint16_t
fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
fat_cluster_t *penult, fat_cluster_t *ult, uint16_t max_clusters)
fat_cluster_t *lastc, uint16_t max_clusters)
{
block_t *b;
unsigned bps;
82,22 → 79,18
 
if (firstc == FAT_CLST_RES0) {
/* No space allocated to the file. */
if (ult)
*ult = firstc;
if (lastc)
*lastc = firstc;
return 0;
}
 
/* At this point, the meaning of penult is not well-defined. */
if (penult)
*penult = FAT_CLST_RES0;
 
while (clst < FAT_CLST_LAST1 && clusters < max_clusters) {
unsigned fsec; /* sector offset relative to FAT1 */
bn_t fsec; /* sector offset relative to FAT1 */
unsigned fidx; /* FAT1 entry index */
 
assert(clst >= FAT_CLST_FIRST);
if (penult)
*penult = clst; /* remember the penultimate cluster */
if (lastc)
*lastc = clst; /* remember the last cluster number */
fsec = (clst * sizeof(fat_cluster_t)) / bps;
fidx = clst % (bps / sizeof(fat_cluster_t));
/* read FAT1 */
108,8 → 101,8
clusters++;
}
 
if (ult)
*ult = clst;
if (lastc && clst < FAT_CLST_LAST1)
*lastc = clst;
 
return clusters;
}
120,13 → 113,13
* @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.
* @param bn Block number.
*
* @return Block structure holding the requested block.
*/
block_t *
_fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc,
off_t offset)
bn_t bn)
{
block_t *b;
unsigned bps;
136,7 → 129,7
unsigned sf;
unsigned ssa; /* size of the system area */
unsigned clusters, max_clusters;
fat_cluster_t lastc, clst = firstc;
fat_cluster_t lastc;
 
bps = uint16_t_le2host(bs->bps);
rscnt = uint16_t_le2host(bs->rscnt);
149,23 → 142,22
 
if (firstc == FAT_CLST_ROOT) {
/* root directory special case */
assert(offset < rds);
b = block_get(dev_handle, rscnt + bs->fatcnt * sf + offset);
assert(bn < rds);
b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn);
return b;
}
 
max_clusters = offset / bs->spc;
clusters = fat_cluster_walk(bs, dev_handle, firstc, NULL, &lastc,
max_clusters = bn / bs->spc;
clusters = fat_cluster_walk(bs, dev_handle, firstc, &lastc,
max_clusters);
assert(clusters == max_clusters);
 
b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc +
offset % bs->spc);
bn % bs->spc);
 
return b;
}
 
 
/** Fill the gap between EOF and a new file position.
*
* @param bs Buffer holding the boot sector for nodep.
210,16 → 202,43
}
}
 
/** Mark cluster in one instance of FAT.
/** Get cluster from the first 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);
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 marked.
* @param value Value mark the cluster with.
* @param clst Cluster which is to be set.
* @param value Value to set the cluster with.
*/
void
fat_mark_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno,
fat_cluster_t clst, fat_cluster_t value)
{
block_t *b;
256,7 → 275,7
 
for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) {
for (c = 0; c < nclsts; c++) {
fat_mark_cluster(bs, dev_handle, fatno, lifo[c],
fat_set_cluster(bs, dev_handle, fatno, lifo[c],
c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]);
}
}
340,7 → 359,7
* we have allocated so far.
*/
while (found--) {
fat_mark_cluster(bs, dev_handle, FAT1, lifo[found],
fat_set_cluster(bs, dev_handle, FAT1, lifo[found],
FAT_CLST_RES0);
}
348,9 → 367,32
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 boot sector of the file system.
* @param bs Buffer holding the boot sector of the file system.
* @param nodep Node representing the file.
* @param mcl First cluster of the cluster chain to append.
*/
360,8 → 402,8
fat_cluster_t lcl;
uint8_t fatno;
 
if (fat_cluster_walk(bs, nodep->idx->dev_handle, nodep->firstc, &lcl,
NULL, (uint16_t) -1) == 0) {
if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl,
(uint16_t) -1) == 0) {
/* No clusters allocated to the node yet. */
nodep->firstc = host2uint16_t_le(mcl);
nodep->dirty = true; /* need to sync node */
369,9 → 411,40
}
 
for (fatno = FAT1; fatno < bs->fatcnt; fatno++)
fat_mark_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl);
fat_set_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/dynload/uspace/srv/fs/fat/fat_fat.h
35,6 → 35,7
 
#include "../../vfs/vfs.h"
#include <stdint.h>
#include <libblock.h>
 
#define FAT1 0
 
58,22 → 59,27
typedef uint16_t fat_cluster_t;
 
#define fat_clusters_get(bs, dh, fc) \
fat_cluster_walk((bs), (dh), (fc), NULL, NULL, (uint16_t) -1)
#define fat_block_get(bs, np, off) \
_fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (off))
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) \
_fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn))
 
extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t,
fat_cluster_t, off_t);
extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t,
fat_cluster_t *, fat_cluster_t *, uint16_t);
fat_cluster_t, bn_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 void fat_mark_cluster(struct fat_bs *, dev_handle_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,
fat_cluster_t, fat_cluster_t);
extern void fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,
off_t);
/branches/dynload/uspace/srv/fs/fat/fat_ops.c
102,6 → 102,42
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.
134,34 → 170,9
assert(idxp->pfc);
 
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);
nodep = fat_node_get_new();
if (!nodep)
return NULL;
 
bs = block_bb_get(idxp->dev_handle);
bps = uint16_t_le2host(bs->bps);
233,7 → 244,7
futex_up(&nodep->lock);
}
 
static void *fat_create(int flags)
static void *fat_create(dev_handle_t dev_handle, int flags)
{
return NULL; /* not supported at the moment */
}
634,6 → 645,7
block_t *b;
uint16_t bps;
unsigned spc;
unsigned bpc; /* bytes per cluster */
off_t boundary;
if (!nodep) {
650,6 → 662,11
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,
658,12 → 675,8
* value signalizing a smaller number of bytes written.
*/
bytes = min(len, bps - pos % bps);
 
bs = block_bb_get(dev_handle);
bps = uint16_t_le2host(bs->bps);
spc = bs->spc;
boundary = ROUND_UP(nodep->size, bps * spc);
boundary = ROUND_UP(nodep->size, bpc);
if (pos < boundary) {
/*
* This is the easier case - we are either overwriting already
681,8 → 694,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 {
/*
693,11 → 706,9
unsigned nclsts;
fat_cluster_t mcl, lcl;
nclsts = (ROUND_UP(pos + bytes, bps * spc) - boundary) /
bps * spc;
nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
/* 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);
719,8 → 730,8
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;
}
}
731,6 → 742,10
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) {
738,24 → 753,45
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) {
/*
* TODO: the standard says we have the freedom to grow the file.
* 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 file is to be shrunk.
* The node will be shrunk, clusters will be deallocated.
*/
rc = ENOTSUP; /* XXX */
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/dynload/boot/arch/ia64/loader/asm.S
37,7 → 37,5
alloc loc0 = ar.pfs, 1, 1, 0, 0
movl r8 = 0x4404000;;
mov b1 = r8 ;;
mov r1 = in0;
mov r1 = in0; #Save bootinfo prt
br.call.sptk.many b0 = b1;;
.global ofw
ofw:
/branches/dynload/boot/arch/ia64/loader/boot.S
34,6 → 34,7
.global start
start:
 
 
mov ar.rsc = r0
# movl r8 = (VRN_KERNEL << VRN_SHIFT) ;;
movl r1 = 0x4400000
57,6 → 58,22
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/dynload/boot/arch/ia64/loader/main.c
34,7 → 34,7
#include <align.h>
#include <balloc.h>
 
bootinfo_t bootinfo;
extern bootinfo_t binfo;
component_t components[COMPONENTS];
 
char *release = RELEASE;
69,6 → 69,8
int ii;
bootinfo_t *bootinfo=&binfo;
//for(ii=0;ii<KERNEL_SIZE;ii++) ((char *)(0x100000))[ii] = ((char *)KERNEL_START)[ii+1];
92,19 → 94,18
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/dynload/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
LOADLIBES = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)
FORMAT = efi-app-$(ARCH)
 
TARGETS = t.efi t2.efi t3.efi t4.efi t5.efi t6.efi printenv.efi t7.efi
/branches/dynload/boot/arch/ia64/loader/gefi/HelenOS/hello.c
1,9 → 1,23
#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)
{
15,24 → 29,7
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)
{
72,11 → 69,12
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));
97,8 → 95,10
}
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,28 → 108,84
buf[j+1]=LoadOptions[i+j];
buf[j+1]=0;
StrCat(FileName,buf);
defaultLoad=0;
}
//Print(L"%s\n",FileName);
 
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;
imageLoad=1;
#ifdef IMAGE_LINKED
if(defaultLoad) {
Print(L"Using Linked Image\n");
imageLoad=0;
}
Size = 0x00400000;
BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer);
FileHandle->Read(FileHandle, &Size, OsKernelBuffer);
FileHandle->Close(FileHandle);
#endif
 
if(Size<1) return 0;
char * HOS;
if(imageLoad)
{
Size = 0x00400000;
 
Vol->OpenVolume (Vol, &CurDir);
 
char * HOS = OsKernelBuffer;
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
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;
167,6 → 223,10
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(
177,8 → 237,6
);
while(1){
((volatile int *)(0x80000000000b8000))[0]++;
}
//Not reached
return EFI_SUCCESS;
}
/branches/dynload/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
LOADLIBES = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)
FORMAT = efi-app-$(ARCH)
 
 
45,16 → 45,29
-j .rela -j .reloc --target=$(FORMAT) hello.so hello.efi
$(OBJDUMP) -d hello.efi > hello.disass
 
hello.so: hello.o image.o
$(LD) $(LDFLAGS) -Map hello.map hello.o -o hello.so $(LOADLIBES)
#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.o: hello.c
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c hello.c -o hello.o
 
image.o: ../../image.boot
 
image.bin: ../../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/dynload/boot/arch/ia64/loader/main.h
29,29 → 29,14
#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);
 
/branches/dynload/boot/arch/ia64/loader/Makefile
88,6 → 88,8
boot.S
 
COMPONENTS = \
$(KERNELDIR)/kernel.bin
NOCOMPONENTS = \
$(KERNELDIR)/kernel.bin \
$(USPACEDIR)/srv/ns/ns \
$(USPACEDIR)/srv/loader/loader \