Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4054 → Rev 4055

/branches/dd/kernel/arch/ia64/include/interrupt.h
50,10 → 50,13
#define IVT_FIRST 0
 
/** External Interrupt vectors. */
 
#define VECTOR_TLB_SHOOTDOWN_IPI 0xf0
#define INTERRUPT_TIMER 255
#define IRQ_KBD 241
#define IRQ_MOUSE 252
#define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE)
#define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE)
#define INTERRUPT_SPURIOUS 15
#define LEGACY_INTERRUPT_BASE 0x20
 
/** General Exception codes. */
#define GE_ILLEGALOP 0
114,7 → 117,7
/*
* The following variables are defined only for break_instruction
* handler.
* handler.
*/
uint64_t in0;
uint64_t in1;
150,6 → 153,8
extern void external_interrupt(uint64_t vector, istate_t *istate);
extern void disabled_fp_register(uint64_t vector, istate_t *istate);
 
extern void trap_virtual_enable_irqs(uint16_t irqmask);
 
#endif
 
/** @}
/branches/dd/kernel/arch/ia64/include/fpu_context.h
35,7 → 35,6
#ifndef KERN_ia64_FPU_CONTEXT_H_
#define KERN_ia64_FPU_CONTEXT_H_
 
#define ARCH_HAS_FPU 1
#define FPU_CONTEXT_ALIGN 16
 
#include <arch/types.h>
/branches/dd/kernel/arch/ia64/include/types.h
35,10 → 35,6
#ifndef KERN_ia64_TYPES_H_
#define KERN_ia64_TYPES_H_
 
#define NULL 0
#define false 0
#define true 1
 
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
69,14 → 65,34
typedef uint64_t unative_t;
typedef int64_t native_t;
 
typedef uint8_t bool;
typedef uint64_t thread_id_t;
typedef uint64_t task_id_t;
typedef uint32_t context_id_t;
typedef struct {
unative_t fnc;
unative_t gp;
} fncptr_t;
 
typedef int32_t inr_t;
typedef int32_t devno_t;
#define PRIp "lx" /**< Format for uintptr_t. */
#define PRIs "lu" /**< Format for size_t. */
#define PRIc "lu" /**< Format for count_t. */
#define PRIi "lu" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
#define PRId32 "d" /**< Format for int32_t. */
#define PRId64 "ld" /**< Format for int64_t. */
#define PRIdn "d" /**< Format for native_t. */
 
#define PRIu8 "u" /**< Format for uint8_t. */
#define PRIu16 "u" /**< Format for uint16_t. */
#define PRIu32 "u" /**< Format for uint32_t. */
#define PRIu64 "lu" /**< Format for uint64_t. */
#define PRIun "u" /**< Format for unative_t. */
 
#define PRIx8 "x" /**< Format for hexadecimal (u)int8_t. */
#define PRIx16 "x" /**< Format for hexadecimal (u)int16_t. */
#define PRIx32 "x" /**< Format for hexadecimal (u)uint32_t. */
#define PRIx64 "lx" /**< Format for hexadecimal (u)int64_t. */
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */
 
#endif
 
/** @}
/branches/dd/kernel/arch/ia64/include/memstr.h
37,10 → 37,10
 
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x);
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x);
extern void memsetw(void *dst, size_t cnt, uint16_t x);
extern void memsetb(void *dst, size_t cnt, uint8_t x);
 
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt);
extern int memcmp(const void *a, const void *b, size_t cnt);
 
#endif
 
/branches/dd/kernel/arch/ia64/include/atomic.h
37,29 → 37,65
 
/** Atomic addition.
*
* @param val Atomic value.
* @param imm Value to add.
* @param val Atomic value.
* @param imm Value to add.
*
* @return Value before addition.
* @return Value before addition.
*/
static inline long atomic_add(atomic_t *val, int imm)
{
long v;
 
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm));
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v),
"+m" (val->count) : "i" (imm));
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); }
 
static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; }
static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; }
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 long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); }
static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); }
 
static inline void atomic_inc(atomic_t *val)
{
atomic_add(val, 1);
}
 
static inline void atomic_dec(atomic_t *val)
{
atomic_add(val, -1);
}
 
static inline long atomic_preinc(atomic_t *val)
{
return atomic_add(val, 1) + 1;
}
 
static inline long atomic_predec(atomic_t *val)
{
return atomic_add(val, -1) - 1;
}
 
static inline long atomic_postinc(atomic_t *val)
{
return atomic_add(val, 1);
}
 
static inline long atomic_postdec(atomic_t *val)
{
return atomic_add(val, -1);
}
 
#endif
 
/** @}
/branches/dd/kernel/arch/ia64/include/arch.h
39,6 → 39,8
 
#include <arch/ski/ski.h>
 
extern void arch_pre_main(void);
 
#endif
 
/** @}
/branches/dd/kernel/arch/ia64/include/proc/task.h
31,14 → 31,19
*/
/** @file
*/
#include <proc/task.h>
 
#ifndef KERN_ia64_TASK_H_
#define KERN_ia64_TASK_H_
 
#include <adt/bitmap.h>
 
typedef struct {
bitmap_t *iomap;
} task_arch_t;
 
#define task_create_arch(t)
 
#define task_create_arch(t) { (t)->arch.iomap = NULL; }
#define task_destroy_arch(t)
 
#endif
/branches/dd/kernel/arch/ia64/include/bootinfo.h
29,13 → 29,23
#ifndef KERN_ia64_BOOTINFO_H_
#define KERN_ia64_BOOTINFO_H_
 
#define BOOTINFO_ADDRESS 0x4401000
 
 
#define CONFIG_INIT_TASKS 32
 
#define MEMMAP_ITEMS 128
 
#define EFI_MEMMAP_FREE_MEM 0
#define EFI_MEMMAP_IO 1
#define EFI_MEMMAP_IO_PORTS 2
 
/** Size of buffer for storing task name in binit_task_t. */
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
typedef struct {
void *addr;
unsigned long size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} binit_task_t;
typedef struct {
43,9 → 53,24
binit_task_t tasks[CONFIG_INIT_TASKS];
} binit_t;
 
typedef struct {
unsigned int type;
unsigned long base;
unsigned long size;
}efi_memmap_item_t;
 
 
typedef struct {
binit_t taskmap;
 
efi_memmap_item_t memmap[MEMMAP_ITEMS];
unsigned int memmap_items;
 
unsigned long * sapic;
unsigned long sys_freq;
unsigned long freq_scale;
unsigned int wakeup_intno;
int hello_configured;
} bootinfo_t;
 
extern bootinfo_t *bootinfo;
/branches/dd/kernel/arch/ia64/include/asm.h
36,29 → 36,72
#define KERN_ia64_ASM_H_
 
#include <config.h>
#include <typedefs.h>
#include <arch/types.h>
#include <arch/register.h>
 
 
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL
 
static inline void outb(uint64_t port,uint8_t v)
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
uintptr_t prt = (uintptr_t) port;
 
*((uint8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
uintptr_t prt = (uintptr_t) port;
 
static inline uint8_t inb(uint64_t port)
*((uint16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
uintptr_t prt = (uintptr_t) port;
 
*((uint32_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
return *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
static inline uint8_t pio_read_8(ioport8_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((uint8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((uint16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((uint32_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
/** Return base address of current stack
*
* Return the base address of the current stack.
69,9 → 112,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.
123,6 → 171,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.
297,7 → 355,8
extern void cpu_sleep(void);
extern void asm_delay_loop(uint32_t t);
 
extern void switch_to_userspace(uintptr_t entry, uintptr_t sp, uintptr_t bsp, uintptr_t uspace_uarg, uint64_t ipsr, uint64_t rsc);
extern void switch_to_userspace(uintptr_t, uintptr_t, uintptr_t, uintptr_t,
uint64_t, uint64_t);
 
#endif
 
/branches/dd/kernel/arch/ia64/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
35,12 → 35,16
#ifndef KERN_ia64_FRAME_H_
#define KERN_ia64_FRAME_H_
 
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
extern void frame_arch_init(void);
#define physmem_print()
 
/branches/dd/kernel/arch/ia64/include/mm/page.h
41,15 → 41,30
#define PAGE_SIZE FRAME_SIZE
#define PAGE_WIDTH FRAME_WIDTH
 
#define PAGE_COLOR_BITS 0 /* dummy */
 
#ifdef KERNEL
 
/** Bit width of the TLB-locked portion of kernel address space. */
#define KERNEL_PAGE_WIDTH 28 /* 256M */
#define IO_PAGE_WIDTH 26 /* 64M */
#define FW_PAGE_WIDTH 28 /* 256M */
 
#define USPACE_IO_PAGE_WIDTH 12 /* 4K */
 
 
/*
* Statically mapped IO spaces - offsets to 0xe...00 of virtual addresses
* because of "minimal virtual bits implemented is 51" it is possible to
* have values up to 0x0007000000000000
*/
 
/* 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
64,8 → 79,8
 
#define REGION_REGISTERS 8
 
#define KA2PA(x) ((uintptr_t) (x-(VRN_KERNEL<<VRN_SHIFT)))
#define PA2KA(x) ((uintptr_t) (x+(VRN_KERNEL<<VRN_SHIFT)))
#define KA2PA(x) ((uintptr_t) (x - (VRN_KERNEL << VRN_SHIFT)))
#define PA2KA(x) ((uintptr_t) (x + (VRN_KERNEL << VRN_SHIFT)))
 
#define VHPT_WIDTH 20 /* 1M */
#define VHPT_SIZE (1 << VHPT_WIDTH)
/branches/dd/kernel/arch/ia64/include/mm/tlb.h
35,9 → 35,6
#ifndef KERN_ia64_TLB_H_
#define KERN_ia64_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#include <arch/mm/page.h>
#include <arch/mm/asid.h>
#include <arch/interrupt.h>
46,8 → 43,8
/** Data and instruction Translation Register indices. */
#define DTR_KERNEL 0
#define ITR_KERNEL 0
#define DTR_KSTACK1 1
#define DTR_KSTACK2 2
#define DTR_KSTACK1 4
#define DTR_KSTACK2 5
 
/** Portion of TLB insertion format data structure. */
union tlb_entry {
/branches/dd/kernel/arch/ia64/include/mm/vhpt.h
44,8 → 44,8
{
vhpt_entry_t ventry;
ventry.word[0]=tentry.word[0];
ventry.word[1]=tentry.word[1];
ventry.word[0] = tentry.word[0];
ventry.word[1] = tentry.word[1];
return ventry;
}
/branches/dd/kernel/arch/ia64/include/register.h
40,11 → 40,11
#define PSR_I_MASK 0x4000
#define PSR_PK_MASK 0x8000
 
#define PSR_DT_MASK (1<<17)
#define PSR_RT_MASK (1<<27)
#define PSR_DT_MASK (1 << 17)
#define PSR_RT_MASK (1 << 27)
 
#define PSR_DFL_MASK (1<<18)
#define PSR_DFH_MASK (1<<19)
#define PSR_DFL_MASK (1 << 18)
#define PSR_DFH_MASK (1 << 19)
 
#define PSR_IT_MASK 0x0000001000000000
 
/branches/dd/kernel/arch/ia64/include/debug.h
1,5 → 1,5
/*
* Copyright (c) 2005
* Copyright (c) 2005 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/branches/dd/kernel/arch/ia64/include/barrier.h
45,9 → 45,33
#define read_barrier() memory_barrier()
#define write_barrier() memory_barrier()
 
#define srlz_i() asm volatile (";; srlz.i ;;\n" ::: "memory")
#define srlz_d() asm volatile (";; srlz.d\n" ::: "memory")
#define srlz_i() \
asm volatile (";; srlz.i ;;\n" ::: "memory")
#define srlz_d() \
asm volatile (";; srlz.d\n" ::: "memory")
 
#define fc_i(a) \
asm volatile ("fc.i %0\n" :: "r" ((a)) : "memory")
#define sync_i() \
asm volatile (";; sync.i\n" ::: "memory")
 
#define smc_coherence(a) \
{ \
fc_i((a)); \
sync_i(); \
srlz_i(); \
}
 
#define FC_INVAL_MIN 32
#define smc_coherence_block(a, l) \
{ \
unsigned long i; \
for (i = 0; i < (l); i += FC_INVAL_MIN) \
fc_i((void *)(a) + i); \
sync_i(); \
srlz_i(); \
}
 
#endif
 
/** @}
/branches/dd/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,32
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;
srlz_d();
 
}
 
#endif
 
/** @}
/branches/dd/kernel/arch/ia64/include/drivers/i8042.h
File deleted
/branches/dd/kernel/arch/ia64/include/drivers/ega.h
File deleted
/branches/dd/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/dd/kernel/arch/ia64/include/drivers/kbd.h
0,0 → 1,46
/*
* Copyright (c) 2006 Jakub Jermar, 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 ia6464
* @{
*/
/** @file
*/
 
#ifndef KERN_ia64_KBD_H_
#define KERN_ia64_KBD_H_
 
#define KBD_UNKNOWN 0
#define KBD_SKI 1
#define KBD_LEGACY 2
#define KBD_NS16550 3
 
#endif
 
/** @}
*/
/branches/dd/kernel/arch/ia64/Makefile.inc
32,11 → 32,8
BFD_NAME = elf64-little
BFD_ARCH = ia64-elf64
TARGET = ia64-pc-linux-gnu
TOOLCHAIN_DIR = /usr/local/ia64
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64
 
INIT0_ADDRESS = 0xe000000004404000
INIT0_SIZE = 0x100000
 
CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127
GCC_CFLAGS += $(CMN1)
ICC_CFLAGS += $(CMN1)
44,58 → 41,35
LFLAGS += -EL
AFLAGS += -mconstant-gp
 
DEFS += -D__64_BITS__ -DINIT0_ADDRESS=$(INIT0_ADDRESS) -DINIT0_SIZE=$(INIT0_SIZE) -D$(MACHINE)
DEFS += -D__64_BITS__
 
 
## Compile with page hash table support.
#
 
CONFIG_PAGE_HT = y
DEFS += -DCONFIG_PAGE_HT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/ia64.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/ivt.S \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/vhpt.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/it.c
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/dummy.s \
arch/$(KARCH)/src/ia64.c \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/ivt.S \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/vhpt.c \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/smp/smp.c \
arch/$(KARCH)/src/drivers/it.c
 
ifeq ($(MACHINE),ski)
ARCH_SOURCES += arch/$(ARCH)/src/ski/ski.c
ARCH_SOURCES += arch/$(KARCH)/src/ski/ski.c
DEFS += -DSKI
# BFD = elf64-ia64-little
BFD = binary
endif
 
ifeq ($(MACHINE),i460GX)
ARCH_SOURCES += arch/$(ARCH)/src/drivers/ega.c
CONFIG_I8042 = y
DEFS += -DI460GX -DCONFIG_I8042
DEFS += -DI460GX
BFD = binary
 
endif
 
/branches/dd/kernel/arch/ia64/src/putchar.c
File deleted
/branches/dd/kernel/arch/ia64/src/fpu_context.c
149,8 → 149,10
"stf.spill [%7] = f127, 0x80\n;;"
 
:
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])),
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])),
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
);
}
267,14 → 269,16
"ldf.fill f127 = [%7], 0x80\n;;"
 
:
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])),
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])),
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
);
}
 
void fpu_enable(void)
{
uint64_t a = 0 ;
uint64_t a = 0;
 
asm volatile (
"rsm %0 ;;"
/branches/dd/kernel/arch/ia64/src/smp/smp.c
0,0 → 1,167
/*
* 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/bootinfo.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();
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 )
{
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])
ipi_send_ipi(id, eid, ipi);
}
 
void smp_init(void)
{
if (!bootinfo->hello_configured)
return;
/*
* If we have not got system prepared by hello, we are not able to start
* AP's. This means we are running on a simulator.
*/
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++;
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) {
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
 
/** @}
*/
 
/branches/dd/kernel/arch/ia64/src/ddi/ddi.c
1,5 → 1,6
/*
* Copyright (c) 2006 Jakub Jermar
* Copyright (c) 2008 Jakub vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
35,19 → 36,39
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <mm/slab.h>
#include <errno.h>
 
#define IO_MEMMAP_PAGES 16384
#define PORTS_PER_PAGE 4
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
* @param task Task.
* @param ioaddr Starting I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
if (!task->arch.iomap) {
uint8_t *map;
 
task->arch.iomap = malloc(sizeof(bitmap_t), 0);
map = malloc(BITS2BYTES(IO_MEMMAP_PAGES), 0);
if(!map)
return ENOMEM;
bitmap_initialize(task->arch.iomap, map, IO_MEMMAP_PAGES);
bitmap_clear_range(task->arch.iomap, 0, IO_MEMMAP_PAGES);
}
uintptr_t iopage = ioaddr / PORTS_PER_PAGE;
size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE);
bitmap_set_range(task->arch.iomap, iopage, size / 4);
 
return 0;
}
 
/branches/dd/kernel/arch/ia64/src/asm.S
51,7 → 51,7
 
adds r14 = 7, in1
mov r2 = ar.lc
mov r8 = in1 ;;
mov r8 = in0
and r14 = -8, r14 ;;
cmp.ne p6, p7 = r14, in1
(p7) br.cond.dpnt 3f ;;
63,7 → 63,7
(p6) mov r17 = r0 ;;
(p6) mov ar.lc = r14
1:
add r14 = r16, r8
add r14 = r16, in1
add r15 = r16, in0
adds r17 = 1, r17 ;;
ld1 r14 = [r14]
72,7 → 72,6
br.cloop.sptk.few 1b ;;
2:
mov ar.lc = r2
 
mov ar.pfs = loc0
br.ret.sptk.many rp
3:
90,7 → 89,7
4:
shladd r14 = r16, 3, r0
adds r16 = 1, r17 ;;
add r15 = r8, r14
add r15 = in1, r14
add r14 = in0, r14
mov r17 = r16 ;;
ld8 r15 = [r15] ;;
104,7 → 103,7
cmp.eq p6, p7 = 0, r15
add in0 = r14, in0
adds r15 = -1, r15
add r17 = r14, r8
add r17 = r14, in1
(p6) br.cond.dpnt 2b ;;
mov ar.lc = r15
6:
116,7 → 115,6
st1 [r15] = r14
br.cloop.sptk.few 6b ;;
mov ar.lc = r2
 
mov ar.pfs = loc0
br.ret.sptk.many rp
130,6 → 128,10
memsetb:
br _memsetb
 
.global memsetw
memsetw:
br _memsetw
 
.global cpu_halt
cpu_halt:
br cpu_halt
163,6 → 165,9
 
xor r1 = r1, r1
/* r2 is defined to hold pcb_ptr - set it to 0 */
xor r2 = r2, r2
mov loc1 = cr.ifs
movl loc2 = PFM_MASK ;;
and loc1 = loc2, loc1 ;;
/branches/dd/kernel/arch/ia64/src/proc/scheduler.c
47,14 → 47,17
{
}
 
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack is mapped in DTR. */
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack
* is mapped in DTR.
*/
void before_thread_runs_arch(void)
{
uintptr_t base;
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH);
base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 
if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<(KERNEL_PAGE_WIDTH))) {
if ((uintptr_t) THREAD->kstack < base ||
(uintptr_t) THREAD->kstack > base + (1 << (KERNEL_PAGE_WIDTH))) {
/*
* Kernel stack of this thread is not mapped by DTR[TR_KERNEL].
* Use DTR[TR_KSTACK1] and DTR[TR_KSTACK2] to map it.
64,8 → 67,11
dtr_purge((uintptr_t) THREAD->kstack, PAGE_WIDTH+1);
/* insert DTR[TR_STACK1] and DTR[TR_STACK2] */
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), true, DTR_KSTACK1);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack + PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true, DTR_KSTACK2);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack,
KA2PA(THREAD->kstack), true, DTR_KSTACK1);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack +
PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true,
DTR_KSTACK2);
}
/*
/branches/dd/kernel/arch/ia64/src/ia64.c
51,64 → 51,99
#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/drivers/legacy/ia32/io.h>
#include <genarch/drivers/ega/ega.h>
#include <genarch/kbrd/kbrd.h>
#include <genarch/srln/srln.h>
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/drivers/ns16550/ns16550.h>
#include <arch/drivers/kbd.h>
#include <smp/smp.h>
#include <smp/ipi.h>
#include <arch/atomic.h>
#include <panic.h>
#include <print.h>
#include <sysinfo/sysinfo.h>
#include <string.h>
 
/* NS16550 as a COM 1 */
#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE)
 
bootinfo_t *bootinfo;
 
static uint64_t iosapic_base = 0xfec00000;
 
/** Performs ia64-specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Setup usermode init tasks. */
 
//#ifdef I460GX
unsigned int i;
init.cnt = bootinfo->taskmap.count;
for (i = 0; i < init.cnt; i++) {
init.tasks[i].addr = ((unsigned long) bootinfo->taskmap.tasks[i].addr) | VRN_MASK;
init.tasks[i].addr =
((unsigned long) bootinfo->taskmap.tasks[i].addr) |
VRN_MASK;
init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
strncpy(init.tasks[i].name, bootinfo->taskmap.tasks[i].name,
CONFIG_TASK_NAME_BUFLEN);
}
/*
#else
init.cnt = 8;
init.tasks[0].addr = INIT0_ADDRESS;
init.tasks[0].size = INIT0_SIZE;
init.tasks[1].addr = INIT0_ADDRESS + 0x400000;
init.tasks[1].size = INIT0_SIZE;
init.tasks[2].addr = INIT0_ADDRESS + 0x800000;
init.tasks[2].size = INIT0_SIZE;
init.tasks[3].addr = INIT0_ADDRESS + 0xc00000;
init.tasks[3].size = INIT0_SIZE;
init.tasks[4].addr = INIT0_ADDRESS + 0x1000000;
init.tasks[4].size = INIT0_SIZE;
init.tasks[5].addr = INIT0_ADDRESS + 0x1400000;
init.tasks[5].size = INIT0_SIZE;
init.tasks[6].addr = INIT0_ADDRESS + 0x1800000;
init.tasks[6].size = INIT0_SIZE;
init.tasks[7].addr = INIT0_ADDRESS + 0x1c00000;
init.tasks[7].size = INIT0_SIZE;
#endif*/
}
 
void arch_pre_mm_init(void)
{
/* Set Interruption Vector Address (i.e. location of interruption vector table). */
/*
* Set Interruption Vector Address (i.e. location of interruption vector
* table).
*/
iva_write((uintptr_t) &ivt);
srlz_d();
}
 
static void iosapic_init(void)
{
uint64_t IOSAPIC = PA2KA((unative_t)(iosapic_base)) | FW_OFFSET;
int i;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
 
for (i = 0; i < 16; i++) {
if (i == 2)
continue; /* Disable Cascade interrupt */
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i;
srlz_d();
((uint32_t *)(IOSAPIC + 0x10))[0] = LEGACY_INTERRUPT_BASE + i;
srlz_d();
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i + 1;
srlz_d();
((uint32_t *)(IOSAPIC + 0x10))[0] = myid << (56 - 32) |
myeid << (48 - 32);
srlz_d();
}
 
}
 
 
void arch_post_mm_init(void)
{
irq_init(INR_COUNT, INR_COUNT);
if (config.cpu_active == 1) {
iosapic_init();
irq_init(INR_COUNT, INR_COUNT);
#ifdef SKI
ski_init_console();
#else
ega_init();
#endif
it_init();
ski_init_console();
#else
ega_init(EGA_BASE, EGA_VIDEORAM);
#endif
}
it_init();
}
 
void arch_post_cpu_init(void)
119,51 → 154,54
{
}
 
 
#ifdef I460GX
#define POLL_INTERVAL 50000 /* 50 ms */
/** Kernel thread for polling keyboard. */
static void i8042_kkbdpoll(void *arg)
{
while (1) {
i8042_poll();
thread_usleep(POLL_INTERVAL);
}
}
#endif
 
void arch_post_smp_init(void)
{
 
if (config.cpu_active == 1) {
/*
* Create thread that polls keyboard.
*/
/*
* Create thread that polls keyboard.
*/
#ifdef SKI
thread_t *t;
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("Cannot create kkbdpoll.");
thread_ready(t);
#endif
 
#ifdef I460GX
devno_t kbd = device_assign_devno();
devno_t mouse = device_assign_devno();
/* keyboard controller */
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE);
devno_t devno = device_assign_devno();
inr_t inr;
 
thread_t *t;
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
 
#ifdef CONFIG_NS16550
inr = NS16550_IRQ;
srln_init(stdin);
(void) ns16550_init((ns16550_t *)NS16550_BASE, devno, inr, NULL, NULL,
&srlnin);
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) NS16550_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) NS16550_BASE);
#else
inr = IRQ_KBD;
kbrd_init(stdin);
(void) i8042_init((i8042_t *)I8042_BASE, devno, inr, &kbrdin);
trap_virtual_enable_irqs(1 << inr);
sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) I8042_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) I8042_BASE);
#endif
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, inr);
#endif
 
}
sysinfo_set_item_val("ia64_iospace", NULL, true);
sysinfo_set_item_val("ia64_iospace.address", NULL, true);
sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET);
}
 
 
/** Enter userspace and never return. */
void userspace(uspace_arg_t *kernel_uarg)
{
172,26 → 210,25
 
psr.value = psr_read();
psr.cpl = PL_USER;
psr.i = true; /* start with interrupts enabled */
psr.i = true; /* start with interrupts enabled */
psr.ic = true;
psr.ri = 0; /* start with instruction #0 */
psr.bn = 1; /* start in bank 0 */
psr.ri = 0; /* start with instruction #0 */
psr.bn = 1; /* start in bank 0 */
 
asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
rsc.loadrs = 0;
rsc.be = false;
rsc.pl = PL_USER;
rsc.mode = 3; /* eager mode */
rsc.mode = 3; /* eager mode */
 
switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE,
(uintptr_t) kernel_uarg->uspace_uarg,
psr.value, rsc.value);
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE -
ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE,
(uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value);
 
while (1) {
while (1)
;
}
}
 
/** Set thread-local-storage pointer.
210,8 → 247,9
{
#ifdef SKI
ski_kbd_grab();
#endif
#endif
}
 
/** Return console to userspace
*
*/
224,9 → 262,27
 
void arch_reboot(void)
{
// TODO
while (1);
pio_write_8((ioport8_t *)0x64, 0xfe);
while (1)
;
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
fptr->fnc = (unative_t) addr;
fptr->gp = ((unative_t *) caller)[1];
return (void *) fptr;
}
 
/** @}
*/
/branches/dd/kernel/arch/ia64/src/ski/ski.c
44,8 → 44,9
#include <proc/thread.h>
#include <synch/spinlock.h>
#include <arch/asm.h>
#include <arch/drivers/kbd.h>
 
#define SKI_KBD_INR 0
#define SKI_KBD_INR 0
 
static irq_t ski_kbd_irq;
static devno_t ski_kbd_devno;
55,9 → 56,6
 
static bool kbd_disabled;
 
static void ski_putchar(chardev_t *d, const char ch);
static int32_t ski_getchar(void);
 
/** Display character on debug console
*
* Use SSC (Simulator System Call) to
66,19 → 64,21
* @param d Character device.
* @param ch Character to be printed.
*/
void ski_putchar(chardev_t *d, const char ch)
static void ski_putchar(chardev_t *d, const char ch, bool silent)
{
asm volatile (
"mov r15 = %0\n"
"mov r32 = %1\n" /* r32 is in0 */
"break 0x80000\n" /* modifies r8 */
:
: "i" (SKI_PUTCHAR), "r" (ch)
: "r15", "in0", "r8"
);
if (ch == '\n')
ski_putchar(d, '\r');
if (!silent) {
asm volatile (
"mov r15 = %0\n"
"mov r32 = %1\n" /* r32 is in0 */
"break 0x80000\n" /* modifies r8 */
:
: "i" (SKI_PUTCHAR), "r" (ch)
: "r15", "in0", "r8"
);
if (ch == '\n')
ski_putchar(d, '\r', false);
}
}
 
/** Ask debug console if a key was pressed.
90,7 → 90,7
*
* @return ASCII code of pressed key or 0 if no key pressed.
*/
int32_t ski_getchar(void)
static int32_t ski_getchar(void)
{
uint64_t ch;
114,10 → 114,10
static char ski_getchar_blocking(chardev_t *d)
{
int ch;
 
while(!(ch = ski_getchar()))
;
if(ch == '\r')
while(!(ch = ski_getchar()));
if (ch == '\r')
ch = '\n';
return (char) ch;
}
128,23 → 128,24
char ch;
static char last;
ipl_t ipl;
 
ipl = interrupts_disable();
 
if (kbd_disabled) {
interrupts_restore(ipl);
return;
}
spinlock_lock(&ski_kbd_irq.lock);
 
ch = ski_getchar();
if(ch == '\r')
ch = '\n';
if (ch) {
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) {
if (ski_kbd_irq.notif_cfg.notify &&
ski_kbd_irq.notif_cfg.answerbox) {
chardev_push_character(&ski_uconsole, ch);
ipc_irq_send_notif(&ski_kbd_irq);
/* XXX: send notification to userspace */
} else {
chardev_push_character(&ski_console, ch);
}
155,9 → 156,10
}
 
if (last) {
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) {
if (ski_kbd_irq.notif_cfg.notify &&
ski_kbd_irq.notif_cfg.answerbox) {
chardev_push_character(&ski_uconsole, 0);
ipc_irq_send_notif(&ski_kbd_irq);
/* XXX: send notification to userspace */
}
last = 0;
}
175,7 → 177,7
/* Called from getc(). */
static void ski_kbd_disable(chardev_t *d)
{
kbd_disabled = true;
kbd_disabled = true;
}
 
/** Decline to service hardware IRQ.
184,7 → 186,7
*
* @return Always IRQ_DECLINE.
*/
static irq_ownership_t ski_kbd_claim(void)
static irq_ownership_t ski_kbd_claim(irq_t *irq)
{
return IRQ_DECLINE;
}
227,6 → 229,9
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, SKI_KBD_INR);
sysinfo_set_item_val("kbd.devno", NULL, ski_kbd_devno);
sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
 
sysinfo_set_item_val("fb", NULL, false);
}
 
void ski_kbd_grab(void)
255,7 → 260,9
void kkbdpoll(void *arg)
{
while (1) {
poll_keyboard();
if (!silent) {
poll_keyboard();
}
thread_usleep(POLL_INTERVAL);
}
}
/branches/dd/kernel/arch/ia64/src/cpu/cpu.c
70,8 → 70,8
}
printf("cpu%d: %s (%s), archrev=%d, model=%d, revision=%d\n", CPU->id,
family_str, vendor, CPU->arch.cpuid3.archrev, CPU->arch.cpuid3.model,
CPU->arch.cpuid3.revision);
family_str, vendor, CPU->arch.cpuid3.archrev,
CPU->arch.cpuid3.model, CPU->arch.cpuid3.revision);
}
 
/** @}
/branches/dd/kernel/arch/ia64/src/mm/tlb.c
92,7 → 92,7
 
/** Invalidate entries belonging to an address space.
*
* @param asid Address space identifier.
* @param asid Address space identifier.
*/
void tlb_invalidate_asid(asid_t asid)
{
131,59 → 131,45
uint64_t ps;
switch (b) {
case 0: /*cnt 1-3*/
case 0: /* cnt 1 - 3 */
ps = PAGE_WIDTH;
break;
case 1: /*cnt 4-15*/
/*cnt=((cnt-1)/4)+1;*/
ps = PAGE_WIDTH+2;
va &= ~((1<<ps)-1);
case 1: /* cnt 4 - 15 */
ps = PAGE_WIDTH + 2;
va &= ~((1 << ps) - 1);
break;
case 2: /*cnt 16-63*/
/*cnt=((cnt-1)/16)+1;*/
ps = PAGE_WIDTH+4;
va &= ~((1<<ps)-1);
case 2: /* cnt 16 - 63 */
ps = PAGE_WIDTH + 4;
va &= ~((1 << ps) - 1);
break;
case 3: /*cnt 64-255*/
/*cnt=((cnt-1)/64)+1;*/
ps = PAGE_WIDTH+6;
va &= ~((1<<ps)-1);
case 3: /* cnt 64 - 255 */
ps = PAGE_WIDTH + 6;
va &= ~((1 << ps) - 1);
break;
case 4: /*cnt 256-1023*/
/*cnt=((cnt-1)/256)+1;*/
ps = PAGE_WIDTH+8;
va &= ~((1<<ps)-1);
case 4: /* cnt 256 - 1023 */
ps = PAGE_WIDTH + 8;
va &= ~((1 << ps) - 1);
break;
case 5: /*cnt 1024-4095*/
/*cnt=((cnt-1)/1024)+1;*/
ps = PAGE_WIDTH+10;
va &= ~((1<<ps)-1);
case 5: /* cnt 1024 - 4095 */
ps = PAGE_WIDTH + 10;
va &= ~((1 << ps) - 1);
break;
case 6: /*cnt 4096-16383*/
/*cnt=((cnt-1)/4096)+1;*/
ps = PAGE_WIDTH+12;
va &= ~((1<<ps)-1);
case 6: /* cnt 4096 - 16383 */
ps = PAGE_WIDTH + 12;
va &= ~((1 << ps) - 1);
break;
case 7: /*cnt 16384-65535*/
case 8: /*cnt 65536-(256K-1)*/
/*cnt=((cnt-1)/16384)+1;*/
ps = PAGE_WIDTH+14;
va &= ~((1<<ps)-1);
case 7: /* cnt 16384 - 65535 */
case 8: /* cnt 65536 - (256K - 1) */
ps = PAGE_WIDTH + 14;
va &= ~((1 << ps) - 1);
break;
default:
/*cnt=((cnt-1)/(16384*16))+1;*/
ps=PAGE_WIDTH+18;
va&=~((1<<ps)-1);
ps = PAGE_WIDTH + 18;
va &= ~((1 << ps) - 1);
break;
}
/*cnt+=(page!=va);*/
for(; va<(page+cnt*(PAGE_SIZE)); va += (1<<ps)) {
asm volatile (
"ptc.l %0,%1;;"
:
: "r" (va), "r" (ps<<2)
);
}
for(; va < (page + cnt * PAGE_SIZE); va += (1 << ps))
asm volatile ("ptc.l %0, %1;;" :: "r" (va), "r" (ps << 2));
srlz_d();
srlz_i();
196,9 → 182,10
 
/** Insert data into data translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
*/
void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
207,9 → 194,10
 
/** Insert data into instruction translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
*/
void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
218,10 → 206,12
 
/** Insert data into instruction or data translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param dtc If true, insert into data translation cache, use
* instruction translation cache otherwise.
*/
void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc)
{
244,19 → 234,20
}
asm volatile (
"mov r8=psr;;\n"
"mov r8 = psr;;\n"
"rsm %0;;\n" /* PSR_IC_MASK */
"srlz.d;;\n"
"srlz.i;;\n"
"mov cr.ifa=%1\n" /* va */
"mov cr.itir=%2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */
"mov cr.ifa = %1\n" /* va */
"mov cr.itir = %2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */
"(p6) itc.i %3;;\n"
"(p7) itc.d %3;;\n"
"mov psr.l=r8;;\n"
"mov psr.l = r8;;\n"
"srlz.d;;\n"
:
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]),
"r" (entry.word[0]), "r" (dtc)
: "p6", "p7", "r8"
);
269,12 → 260,14
 
/** Insert data into instruction translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param tr Translation register.
*/
void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
void
itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
{
tr_mapping_insert(va, asid, entry, false, tr);
}
281,12 → 274,14
 
/** Insert data into data translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param tr Translation register.
*/
void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
void
dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
{
tr_mapping_insert(va, asid, entry, true, tr);
}
293,13 → 288,17
 
/** Insert data into instruction or data translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param dtr If true, insert into data translation register, use instruction translation register otherwise.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param dtr If true, insert into data translation register, use
* instruction translation register otherwise.
* @param tr Translation register.
*/
void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
void
tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr,
index_t tr)
{
region_register rr;
bool restore_rr = false;
320,19 → 319,20
}
 
asm volatile (
"mov r8=psr;;\n"
"mov r8 = psr;;\n"
"rsm %0;;\n" /* PSR_IC_MASK */
"srlz.d;;\n"
"srlz.i;;\n"
"mov cr.ifa=%1\n" /* va */
"mov cr.itir=%2;;\n" /* entry.word[1] */
"cmp.eq p6,p7=%5,r0;;\n" /* decide between itr and dtr */
"(p6) itr.i itr[%4]=%3;;\n"
"(p7) itr.d dtr[%4]=%3;;\n"
"mov psr.l=r8;;\n"
"mov cr.ifa = %1\n" /* va */
"mov cr.itir = %2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %5,r0;;\n" /* decide between itr and dtr */
"(p6) itr.i itr[%4] = %3;;\n"
"(p7) itr.d dtr[%4] = %3;;\n"
"mov psr.l = r8;;\n"
"srlz.d;;\n"
:
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]),
"r" (entry.word[0]), "r" (tr), "r" (dtr)
: "p6", "p7", "r8"
);
345,12 → 345,15
 
/** Insert data into DTLB.
*
* @param page Virtual page address including VRN bits.
* @param frame Physical frame address.
* @param dtr If true, insert into data translation register, use data translation cache otherwise.
* @param tr Translation register if dtr is true, ignored otherwise.
* @param page Virtual page address including VRN bits.
* @param frame Physical frame address.
* @param dtr If true, insert into data translation register, use data
* translation cache otherwise.
* @param tr Translation register if dtr is true, ignored otherwise.
*/
void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr)
void
dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr,
index_t tr)
{
tlb_entry_t entry;
376,18 → 379,18
*
* Purge DTR entries used by the kernel.
*
* @param page Virtual page address including VRN bits.
* @param width Width of the purge in bits.
* @param page Virtual page address including VRN bits.
* @param width Width of the purge in bits.
*/
void dtr_purge(uintptr_t page, count_t width)
{
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width<<2));
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width << 2));
}
 
 
/** Copy content of PTE into data translation cache.
*
* @param t PTE.
* @param t PTE.
*/
void dtc_pte_copy(pte_t *t)
{
413,7 → 416,7
 
/** Copy content of PTE into instruction translation cache.
*
* @param t PTE.
* @param t PTE.
*/
void itc_pte_copy(pte_t *t)
{
440,8 → 443,8
 
/** Instruction TLB fault handler for faults with VHPT turned off.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate)
{
469,16 → 472,77
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
}
 
static int is_io_page_accessible(int page)
{
if (TASK->arch.iomap)
return bitmap_get(TASK->arch.iomap, page);
else
return 0;
}
 
#define IO_FRAME_BASE 0xFFFFC000000
 
/**
* There is special handling of memory mapped legacy io, because of 4KB sized
* access for userspace.
*
* @param va Virtual address of page fault.
* @param istate Structure with saved interruption state.
*
* @return One on success, zero on failure.
*/
static int try_memmap_io_insertion(uintptr_t va, istate_t *istate)
{
if ((va >= IO_OFFSET ) && (va < IO_OFFSET + (1 << IO_PAGE_WIDTH))) {
if (TASK) {
uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >>
USPACE_IO_PAGE_WIDTH;
 
if (is_io_page_accessible(io_page)) {
uint64_t page, frame;
 
page = IO_OFFSET +
(1 << USPACE_IO_PAGE_WIDTH) * io_page;
frame = IO_FRAME_BASE +
(1 << USPACE_IO_PAGE_WIDTH) * io_page;
 
tlb_entry_t entry;
entry.word[0] = 0;
entry.word[1] = 0;
entry.p = true; /* present */
entry.ma = MA_UNCACHEABLE;
entry.a = true; /* already accessed */
entry.d = true; /* already dirty */
entry.pl = PL_USER;
entry.ar = AR_READ | AR_WRITE;
entry.ppn = frame >> PPN_SHIFT;
entry.ps = USPACE_IO_PAGE_WIDTH;
dtc_mapping_insert(page, TASK->as->asid, entry);
return 1;
} else {
fault_if_from_uspace(istate,
"IO access fault at %p.", va);
}
}
}
return 0;
}
 
/** Data TLB fault handler for faults with VHPT turned off.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void alternate_data_tlb_fault(uint64_t vector, istate_t *istate)
{
511,13 → 575,17
dtc_pte_copy(t);
page_table_unlock(AS, true);
} else {
page_table_unlock(AS, true);
if (try_memmap_io_insertion(va, istate))
return;
/*
* Forward the page fault to the address space page fault handler.
* Forward the page fault to the address space page fault
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
}
526,18 → 594,18
*
* This fault should not occur.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_nested_tlb_fault(uint64_t vector, istate_t *istate)
{
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Data Dirty bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_dirty_bit_fault(uint64_t vector, istate_t *istate)
{
562,10 → 630,9
dtc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->d = true;
dtc_pte_copy(t);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
573,8 → 640,8
 
/** Instruction access bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void instruction_access_bit_fault(uint64_t vector, istate_t *istate)
{
599,10 → 666,9
itc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->a = true;
itc_pte_copy(t);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
636,10 → 702,9
dtc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->a = true;
itc_pte_copy(t);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
678,11 → 743,19
} else {
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d\n", __func__, va, rid);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d.", __func__, va, rid);
}
}
}
 
void tlb_arch_init(void)
{
}
 
void tlb_print(void)
{
}
 
/** @}
*/
/branches/dd/kernel/arch/ia64/src/mm/vhpt.c
41,7 → 41,8
 
uintptr_t vhpt_set_up(void)
{
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH, FRAME_KA | FRAME_ATOMIC);
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH,
FRAME_KA | FRAME_ATOMIC);
if (!vhpt_base)
panic("Kernel configured with VHPT but no memory for table.");
vhpt_invalidate_all();
81,7 → 82,7
 
void vhpt_invalidate_all()
{
memsetb((uintptr_t) vhpt_base, 1 << VHPT_WIDTH, 0);
memsetb(vhpt_base, 1 << VHPT_WIDTH, 0);
}
 
void vhpt_invalidate_asid(asid_t asid)
/branches/dd/kernel/arch/ia64/src/mm/as.c
68,7 → 68,7
continue;
rr.word = rr_read(i);
rr.map.ve = false; /* disable VHPT walker */
rr.map.ve = false; /* disable VHPT walker */
rr.map.rid = ASID2RID(as->asid, i);
rr.map.ps = PAGE_WIDTH;
rr_write(i, rr.word);
/branches/dd/kernel/arch/ia64/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
36,26 → 36,55
#include <mm/frame.h>
#include <config.h>
#include <panic.h>
#include <arch/bootinfo.h>
#include <align.h>
#include <macros.h>
 
/*
* This is Ski-specific and certainly not sufficient
* for real ia64 systems that provide memory map.
*/
#define MEMORY_SIZE (64 * 1024 * 1024)
#define MEMORY_BASE (64 * 1024 * 1024)
#define KERNEL_RESERVED_AREA_BASE (0x4400000)
#define KERNEL_RESERVED_AREA_SIZE (16 * 1024 * 1024)
 
#define ROM_BASE 0xa0000 //For ski
#define ROM_SIZE (384 * 1024) //For ski
void poke_char(int x,int y,char ch, char c);
#define ROM_BASE 0xa0000 /* for simulators */
#define ROM_SIZE (384 * 1024) /* for simulators */
 
#define MIN_ZONE_SIZE (64 * 1024)
 
#define MINCONF 1
 
uintptr_t last_frame = 0;
 
void frame_arch_init(void)
{
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));
if (config.cpu_active == 1) {
unsigned int i;
for (i = 0; i < bootinfo->memmap_items; i++) {
if (bootinfo->memmap[i].type == EFI_MEMMAP_FREE_MEM) {
uint64_t base = bootinfo->memmap[i].base;
uint64_t size = bootinfo->memmap[i].size;
uint64_t abase = ALIGN_UP(base, FRAME_SIZE);
 
if (size > FRAME_SIZE)
size -= abase - base;
 
if (size > MIN_ZONE_SIZE) {
zone_create(abase >> FRAME_WIDTH,
size >> FRAME_WIDTH,
max(MINCONF, abase >> FRAME_WIDTH),
0);
}
if (abase + size > last_frame)
last_frame = abase + size;
}
}
/*
* Blacklist ROM regions.
*/
frame_mark_unavailable(ADDR2PFN(ROM_BASE),
SIZE2FRAMES(ROM_SIZE));
 
frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE),
SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE));
}
}
 
/** @}
/branches/dd/kernel/arch/ia64/src/mm/page.c
27,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
47,6 → 47,7
#include <arch/asm.h>
#include <arch/barrier.h>
#include <memstr.h>
#include <align.h>
 
static void set_environment(void);
 
62,9 → 63,9
void set_environment(void)
{
region_register rr;
pta_register pta;
pta_register pta;
int i;
#ifdef CONFIG_VHPT
#ifdef CONFIG_VHPT
uintptr_t vhpt_base;
#endif
 
122,10 → 123,10
*
* Interrupts must be disabled.
*
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
*
* @return VHPT entry address.
* @return VHPT entry address.
*/
vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid)
{
166,10 → 167,11
*
* Interrupts must be disabled.
*
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
*
* @return True if page and asid match the page and asid of t, false otherwise.
* @return True if page and asid match the page and asid of t,
* false otherwise.
*/
bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v)
{
210,12 → 212,15
/** Set up one VHPT entry.
*
* @param v VHPT entry to be set up.
* @param page Virtual address of the page mapped by the entry.
* @param asid Address space identifier of the address space to which page belongs.
* @param frame Physical address of the frame to wich page is mapped.
* @param flags Different flags for the mapping.
* @param page Virtual address of the page mapped by the entry.
* @param asid Address space identifier of the address space to which
* page belongs.
* @param frame Physical address of the frame to wich page is mapped.
* @param flags Different flags for the mapping.
*/
void vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, int flags)
void
vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame,
int flags)
{
region_register rr_save, rr;
index_t vrn;
249,7 → 254,8
v->word[3] = 0;
v->present.p = true;
v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE;
v->present.ma = (flags & PAGE_CACHEABLE) ?
MA_WRITEBACK : MA_UNCACHEABLE;
v->present.a = false; /* not accessed */
v->present.d = false; /* not dirty */
v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
262,5 → 268,11
v->present.tag.tag_word = tag;
}
 
uintptr_t hw_map(uintptr_t physaddr, size_t size __attribute__ ((unused)))
{
/* THIS is a dirty hack. */
return (uintptr_t)((uint64_t)(PA2KA(physaddr)) + VIO_OFFSET);
}
 
/** @}
*/
/branches/dd/kernel/arch/ia64/src/interrupt.c
53,6 → 53,7
#include <ipc/irq.h>
#include <ipc/ipc.h>
#include <synch/spinlock.h>
#include <mm/tlb.h>
 
#define VECTORS_64_BUNDLE 20
#define VECTORS_16_BUNDLE 48
185,21 → 186,21
break;
}
 
fault_if_from_uspace(istate, "General Exception (%s)", desc);
fault_if_from_uspace(istate, "General Exception (%s).", desc);
 
dump_interrupted_context(istate);
panic("General Exception (%s)\n", desc);
panic("General Exception (%s).", desc);
}
 
void disabled_fp_register(uint64_t vector, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "Interruption: %#hx (%s)",
fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
(uint16_t) vector, vector_to_string(vector));
dump_interrupted_context(istate);
panic("Interruption: %#hx (%s)\n", (uint16_t) vector,
panic("Interruption: %#hx (%s).", (uint16_t) vector,
vector_to_string(vector));
#endif
}
227,40 → 228,82
 
void universal_handler(uint64_t vector, istate_t *istate)
{
fault_if_from_uspace(istate, "Interruption: %#hx (%s)\n",
fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
(uint16_t) vector, vector_to_string(vector));
dump_interrupted_context(istate);
panic("Interruption: %#hx (%s)\n", (uint16_t) vector,
panic("Interruption: %#hx (%s).", (uint16_t) vector,
vector_to_string(vector));
}
 
static void end_of_local_irq(void)
{
asm volatile ("mov cr.eoi=r0;;");
}
 
 
void external_interrupt(uint64_t vector, istate_t *istate)
{
cr_ivr_t ivr;
irq_t *irq;
cr_ivr_t ivr;
ivr.value = ivr_read();
srlz_d();
 
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
switch (ivr.vector) {
case INTERRUPT_SPURIOUS:
switch (ivr.vector) {
case INTERRUPT_SPURIOUS:
#ifdef CONFIG_DEBUG
printf("cpu%d: spurious interrupt\n", CPU->id);
printf("cpu%d: spurious interrupt\n", CPU->id);
#endif
break;
break;
 
default:
panic("\nUnhandled External Interrupt Vector %d\n",
#ifdef CONFIG_SMP
case VECTOR_TLB_SHOOTDOWN_IPI:
tlb_shootdown_ipi_recv();
end_of_local_irq();
break;
#endif
 
case INTERRUPT_TIMER:
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
panic("Unhandled Internal Timer Interrupt (%d).",
ivr.vector);
break;
}
break;
default:
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Send EOI before processing the interrupt */
end_of_local_irq();
}
irq->handler(irq);
if (!irq->preack)
end_of_local_irq();
spinlock_unlock(&irq->lock);
} else {
/*
* Unhandled interrupt.
*/
end_of_local_irq();
#ifdef CONFIG_DEBUG
printf("\nUnhandled External Interrupt Vector %d\n",
ivr.vector);
#endif
}
break;
}
}
 
void trap_virtual_enable_irqs(uint16_t irqmask)
{
}
 
/** @}
*/
/branches/dd/kernel/arch/ia64/src/drivers/ega.c
File deleted
/branches/dd/kernel/arch/ia64/src/drivers/it.c
44,25 → 44,44
#include <ddi/device.h>
#include <arch.h>
 
#define IT_SERVICE_CLOCKS 64
#define IT_SERVICE_CLOCKS 64
 
#define FREQ_NUMERATOR_SHIFT 32
#define FREQ_NUMERATOR_MASK 0xffffffff00000000ULL
 
#define FREQ_DENOMINATOR_SHIFT 0
#define FREQ_DENOMINATOR_MASK 0xffffffffULL
 
uint64_t it_delta;
 
static irq_t it_irq;
 
static irq_ownership_t it_claim(void);
static void it_interrupt(irq_t *irq, void *arg, ...);
static irq_ownership_t it_claim(irq_t *);
static void it_interrupt(irq_t *);
 
/** Initialize Interval Timer. */
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;
85,13 → 104,13
*
* @return Always IRQ_ACCEPT.
*/
irq_ownership_t it_claim(void)
irq_ownership_t it_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Process Interval Timer interrupt. */
void it_interrupt(irq_t *irq, void *arg, ...)
void it_interrupt(irq_t *irq)
{
int64_t c;
int64_t m;
/branches/dd/kernel/arch/ia64/src/start.S
32,19 → 32,15
#include <mm/asid.h>
 
#define RR_MASK (0xFFFFFFFF00000002)
#define RID_SHIFT 8
#define PS_SHIFT 2
#define RID_SHIFT 8
#define PS_SHIFT 2
 
#define KERNEL_TRANSLATION_I 0x0010000000000661
#define KERNEL_TRANSLATION_D 0x0010000000000661
#define KERNEL_TRANSLATION_VIO 0x0010000000000671
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671
#define VIO_OFFSET 0x0002000000000000
#define KERNEL_TRANSLATION_I 0x0010000000000661
#define KERNEL_TRANSLATION_D 0x0010000000000661
#define KERNEL_TRANSLATION_VIO 0x0010000000000671
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671
#define KERNEL_TRANSLATION_FW 0x00100000F0000671
 
#define IO_OFFSET 0x0001000000000000
 
 
 
.section K_TEXT_START, "ax"
 
.global kernel_image_start
53,6 → 49,19
kernel_image_start:
.auto
 
#ifdef CONFIG_SMP
# Identify 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
#endif
 
mov psr.l = r0
srlz.i
srlz.d
59,39 → 68,29
 
# Fill TR.i and TR.d using Region Register #VRN_KERNEL
 
 
movl r8 = (VRN_KERNEL << VRN_SHIFT)
mov r9 = rr[r8]
 
 
movl r10 = (RR_MASK)
and r9 = r10, r9
movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT))
or r9 = r10, r9
 
 
mov rr[r8] = r9
 
 
 
movl r8 = (VRN_KERNEL << VRN_SHIFT)
mov cr.ifa = r8
 
mov r11 = cr.itir ;;
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT);;
or r10 =r10 , r11 ;;
mov cr.itir = r10;;
mov r11 = cr.itir
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT)
or r10 = r10, r11
mov cr.itir = r10
 
movl r10 = (KERNEL_TRANSLATION_I)
itr.i itr[r0] = r10
 
movl r10 = (KERNEL_TRANSLATION_D)
itr.d dtr[r0] = r10
 
 
movl r7 = 1
movl r8 = (VRN_KERNEL << VRN_SHIFT) | VIO_OFFSET
mov cr.ifa = r8
98,15 → 97,13
movl r10 = (KERNEL_TRANSLATION_VIO)
itr.d dtr[r7] = r10
 
mov r11 = cr.itir
movl r10 = ~0xfc
and r10 = r10, r11
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT)
or r10 = r10, r11
mov cr.itir = r10
 
mov r11 = cr.itir ;;
movl r10 = ~0xfc;;
and r10 =r10 , r11 ;;
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT);;
or r10 =r10 , r11 ;;
mov cr.itir = r10;;
 
 
movl r7 = 2
movl r8 = (VRN_KERNEL << VRN_SHIFT) | IO_OFFSET
mov cr.ifa = r8
113,12 → 110,26
movl r10 = (KERNEL_TRANSLATION_IO)
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
# Initialize PSR
 
movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK) /* Enable paging */
mov r9 = psr
 
or r10 = r10, r9
mov cr.ipsr = r10
mov cr.ifs = r0
128,11 → 139,14
srlz.i
 
.explicit
 
/*
* Return From Interupt is the only the way to fill upper half word of PSR.
* Return From Interrupt is the only way to
* fill the upper half word of PSR.
*/
rfi;;
rfi ;;
 
 
.global paging_start
paging_start:
 
140,45 → 154,64
* Now we are paging.
*/
 
# switch to register bank 1
# Switch to register bank 1
bsw.1
 
#ifdef CONFIG_SMP
# Am I BSP or AP?
movl r20 = bsp_started ;;
ld8 r20 = [r20] ;;
cmp.eq p3, p2 = r20, r0 ;;
#else
cmp.eq p3, p2 = r0, r0 ;; /* you are BSP */
#endif /* CONFIG_SMP */
# initialize register stack
# Initialize register stack
mov ar.rsc = r0
movl r8 = (VRN_KERNEL << VRN_SHIFT) ;;
mov ar.bspstore = r8
loadrs
 
# initialize memory stack to some sane value
# Initialize memory stack to some sane value
movl r12 = stack0 ;;
add r12 = -16, r12 /* allocate a scratch area on the stack */
 
# initialize gp (Global Pointer) register
# Initialize gp (Global Pointer) register
movl r20 = (VRN_KERNEL << VRN_SHIFT);;
or r20 = r20,r1;;
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 ;;
 
#ifdef CONFIG_SMP
(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 ;;
#endif
 
br.call.sptk.many b0 = arch_pre_main
 
movl r18 = main_bsp ;;
185,6 → 218,51
mov b1 = r18 ;;
br.call.sptk.many b0 = b1
 
 
0:
br 0b
 
#ifdef CONFIG_SMP
 
.align 4096
kernel_image_ap_start:
.auto
 
# Identify 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 synchro 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
 
#endif /* CONFIG_SMP */