Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1830 → Rev 1831

/trunk/kernel/arch/xen32/include/boot/boot.h
49,6 → 49,9
 
#define mp_map ((pfn_t *) XEN_VIRT_START)
 
#define SIF_PRIVILEGED (1 << 0) /**< Privileged domain */
#define SIF_INITDOMAIN (1 << 1) /**< Iinitial control domain */
 
#include <arch/types.h>
 
typedef uint32_t evtchn_t;
101,7 → 104,7
uint32_t flags; /**< SIF_xxx flags */
pfn_t store_mfn; /**< Shared page (machine page) */
evtchn_t store_evtchn; /**< Event channel for store communication */
void *console_mfn; /**< Console page (machine address) */
pfn_t console_mfn; /**< Console page (machine page) */
evtchn_t console_evtchn; /**< Event channel for console messages */
pte_t *ptl0; /**< Boot PTL0 (kernel address) */
uint32_t pt_frames; /**< Number of bootstrap page table frames */
/trunk/kernel/arch/xen32/include/asm.h
41,10 → 41,6
#include <arch/barrier.h>
#include <config.h>
 
extern uint32_t interrupt_handler_size;
 
extern void interrupt_handlers(void);
 
extern void enable_l_apic_in_msr(void);
 
 
/trunk/kernel/arch/xen32/include/hypercall.h
40,14 → 40,27
uint8_t vector; /**< Exception vector */
uint8_t flags; /**< 0-3: privilege level; 4: clear event enable */
uint16_t cs; /**< Code selector */
uintptr_t address; /**< Code offset */
void *address; /**< Code offset */
} trap_info_t;
 
 
typedef struct {
evtchn_t port;
} evtchn_send_t;
 
typedef struct {
uint32_t cmd;
union {
evtchn_send_t send;
};
} evtchn_op_t;
 
 
#define XEN_SET_TRAP_TABLE 0
#define XEN_MMU_UPDATE 1
#define XEN_SET_CALLBACKS 4
#define XEN_UPDATE_VA_MAPPING 14
#define XEN_EVENT_CHANNEL_OP 16
#define XEN_VERSION 17
#define XEN_CONSOLE_IO 18
#define XEN_VM_ASSIST 21
78,6 → 91,9
#define MMUEXT_NEW_USER_BASEPTR 15
 
 
#define EVTCHNOP_SEND 4
 
 
#define UVMF_NONE 0 /**< No flushing at all */
#define UVMF_TLB_FLUSH 1 /**< Flush entire TLB(s) */
#define UVMF_INVLPG 2 /**< Flush only one entry */
226,4 → 242,13
return hypercall2(XEN_VERSION, cmd, arg);
}
 
static inline int xen_notify_remote(evtchn_t channel)
{
evtchn_op_t op;
op.cmd = EVTCHNOP_SEND;
op.send.port = channel;
return hypercall1(XEN_EVENT_CHANNEL_OP, &op);
}
 
#endif
/trunk/kernel/arch/xen32/src/asm.S
37,7 → 37,6
.global xen_callback
.global xen_failsafe_callback
.global enable_l_apic_in_msr
.global interrupt_handlers
.global memcpy
.global memcpy_from_uspace
.global memcpy_from_uspace_failover_address
123,149 → 122,3
 
pop %eax
ret
 
# Clear nested flag
# overwrites %ecx
.macro CLEAR_NT_FLAG
pushfl
pop %ecx
and $0xffffbfff,%ecx
push %ecx
popfl
.endm
 
## Declare interrupt handlers
#
# Declare interrupt handlers for n interrupt
# vectors starting at vector i.
#
# The handlers setup data segment registers
# and call exc_dispatch().
#
#define INTERRUPT_ALIGN 64
.macro handler i n
 
.ifeq \i-0x30 # Syscall handler
push %ds
push %es
push %fs
push %gs
 
# Push arguments on stack
push %edi
push %esi
push %edx
push %ecx
push %eax
# we must fill the data segment registers
movw $16,%ax
movw %ax,%ds
movw %ax,%es
sti
call syscall_handler # syscall_handler(ax,cx,dx,si,di)
cli
addl $20, %esp # clean-up of parameters
pop %gs
pop %fs
pop %es
pop %ds
CLEAR_NT_FLAG
iret
.else
/*
* This macro distinguishes between two versions of ia32 exceptions.
* One version has error word and the other does not have it.
* The latter version fakes the error word on the stack so that the
* handlers and istate_t can be the same for both types.
*/
.iflt \i-32
.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
/*
* With error word, do nothing
*/
.else
/*
* Version without error word,
*/
subl $4, %esp
.endif
.else
/*
* Version without error word,
*/
subl $4, %esp
.endif
push %ds
push %es
push %fs
push %gs
 
#ifdef CONFIG_DEBUG_ALLREGS
push %ebx
push %ebp
push %edi
push %esi
#else
sub $16, %esp
#endif
push %edx
push %ecx
push %eax
# we must fill the data segment registers
movw $16,%ax
movw %ax,%ds
movw %ax,%es
 
pushl %esp # *istate
pushl $(\i) # intnum
call exc_dispatch # excdispatch(intnum, *istate)
addl $8,%esp # Clear arguments from stack
 
CLEAR_NT_FLAG # Modifies %ecx
pop %eax
pop %ecx
pop %edx
#ifdef CONFIG_DEBUG_ALLREGS
pop %esi
pop %edi
pop %ebp
pop %ebx
#else
add $16, %esp
#endif
pop %gs
pop %fs
pop %es
pop %ds
 
addl $4,%esp # Skip error word, no matter whether real or fake.
iret
.endif
 
.align INTERRUPT_ALIGN
.if (\n-\i)-1
handler "(\i+1)",\n
.endif
.endm
 
# keep in sync with pm.h !!!
IDT_ITEMS=64
.align INTERRUPT_ALIGN
interrupt_handlers:
h_start:
handler 0 IDT_ITEMS
h_end:
 
.data
.global interrupt_handler_size
 
interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
/trunk/kernel/arch/xen32/src/pm.c
103,6 → 103,10
memsetb((uintptr_t) t, sizeof(struct tss), 0);
}
 
static void trap(void)
{
}
 
void traps_init(void)
{
index_t i;
116,7 → 120,7
traps[i].flags = 0;
traps[i].cs = XEN_CS;
traps[i].address = ((uintptr_t) interrupt_handlers) + i * interrupt_handler_size;
traps[i].address = trap;
exc_register(i, "undef", (iroutine) null_interrupt);
}
traps[IDT_ITEMS].vector = 0;
/trunk/kernel/arch/xen32/src/drivers/xconsole.c
39,7 → 39,20
#include <console/chardev.h>
#include <console/console.h>
#include <arch/hypercall.h>
#include <mm/frame.h>
 
#define MASK_INDEX(index, ring) ((index) & (sizeof(ring) - 1))
 
typedef struct {
char in[1024];
char out[2048];
uint32_t in_cons;
uint32_t in_prod;
uint32_t out_cons;
uint32_t out_prod;
} xencons_t;
 
static bool asynchronous = false;
static void xen_putchar(chardev_t *d, const char ch);
 
chardev_t xen_console;
51,11 → 64,33
{
chardev_initialize("xen_out", &xen_console, &xen_ops);
stdout = &xen_console;
if (!(start_info.flags & SIF_INITDOMAIN))
asynchronous = true;
}
 
void xen_putchar(chardev_t *d, const char ch)
{
xen_console_io(CONSOLE_IO_WRITE, 1, &ch);
if (asynchronous) {
xencons_t *console = (xencons_t *) PA2KA(MA2PA(PFN2ADDR(start_info.console_mfn)));
uint32_t cons = console->out_cons;
uint32_t prod = console->out_prod;
memory_barrier();
if ((prod - cons) > sizeof(console->out))
return;
if (ch == '\n')
console->out[MASK_INDEX(prod++, console->out)] = '\r';
console->out[MASK_INDEX(prod++, console->out)] = ch;
write_barrier();
console->out_prod = prod;
xen_notify_remote(start_info.console_evtchn);
} else
xen_console_io(CONSOLE_IO_WRITE, 1, &ch);
}
 
/** @}