/branches/dynload/kernel/arch/ia64/src/ia64.c |
---|
60,13 → 60,16 |
#include <arch/atomic.h> |
#include <panic.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
/*NS16550 as a COM 1*/ |
#define NS16550_IRQ 4 |
#define NS16550_IRQ (4+LAGACY_INTERRUPT_BASE) |
#define NS16550_PORT 0x3f8 |
bootinfo_t *bootinfo; |
static uint64_t iosapic_base=0xfec00000; |
void arch_pre_main(void) |
{ |
/* Setup usermode init tasks. */ |
110,10 → 113,40 |
} |
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]=LAGACY_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) |
{ |
if(config.cpu_active==1) |
{ |
iosapic_init(); |
irq_init(INR_COUNT, INR_COUNT); |
#ifdef SKI |
ski_init_console(); |
121,7 → 154,8 |
ega_init(); |
#endif |
} |
it_init(); |
it_init(); |
} |
void arch_post_cpu_init(void) |
139,9 → 173,14 |
static void i8042_kkbdpoll(void *arg) |
{ |
while (1) { |
i8042_poll(); |
#ifdef CONFIG_NS16550 |
#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN |
ns16550_poll(); |
#endif |
#else |
#ifndef CONFIG_I8042_INTERRUPT_DRIVEN |
i8042_poll(); |
#endif |
#endif |
thread_usleep(POLL_INTERVAL); |
} |
148,6 → 187,14 |
} |
#endif |
void end_of_irq_void(void *cir_arg __attribute__((unused)),inr_t inr __attribute__((unused))); |
void end_of_irq_void(void *cir_arg __attribute__((unused)),inr_t inr __attribute__((unused))) |
{ |
return; |
} |
void arch_post_smp_init(void) |
{ |
165,13 → 212,13 |
#ifdef I460GX |
devno_t kbd = device_assign_devno(); |
devno_t mouse = device_assign_devno(); |
/* keyboard controller */ |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
#ifdef CONFIG_NS16550 |
ns16550_init(kbd, NS16550_IRQ, NS16550_PORT); // as a COM 1 |
ns16550_init(kbd, NS16550_PORT, NS16550_IRQ,end_of_irq_void,NULL); // as a COM 1 |
#else |
devno_t mouse = device_assign_devno(); |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
#endif |
thread_t *t; |
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
182,6 → 229,15 |
#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); |
} |
231,6 → 287,12 |
{ |
#ifdef SKI |
ski_kbd_grab(); |
#else |
#ifdef CONFIG_NS16550 |
ns16550_grab(); |
#else |
i8042_grab(); |
#endif |
#endif |
} |
/** Return console to userspace |
240,6 → 302,13 |
{ |
#ifdef SKI |
ski_kbd_release(); |
#else |
#ifdef CONFIG_NS16550 |
ns16550_release(); |
#else |
i8042_release(); |
#endif |
#endif |
} |
/branches/dynload/kernel/arch/ia64/src/ski/ski.c |
---|
44,6 → 44,7 |
#include <proc/thread.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#include <arch/drivers/kbd.h> |
#define SKI_KBD_INR 0 |
227,6 → 228,7 |
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); |
} |
void ski_kbd_grab(void) |
/branches/dynload/kernel/arch/ia64/src/smp/smp.c |
---|
87,7 → 87,6 |
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++) |
97,12 → 96,28 |
void ipi_broadcast_arch(int ipi ) |
{ |
ipi_broadcast_arch_all(ipi); |
int id,eid; |
int myid,myeid; |
myid=ia64_get_cpu_id(); |
myeid=ia64_get_cpu_eid(); |
//printf("Sending ipi %d on %d\n",ipi,CPU->id); |
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 system prepared by hello, we are not able to start AP's |
//this means we are running on simulator |
sapic_init(); |
ipi_broadcast_arch_all(bootinfo->wakeup_intno); |
volatile long long brk; |
115,7 → 130,6 |
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; |
} |
/branches/dynload/kernel/arch/ia64/src/ddi/ddi.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* Copyright (c) 2006 Jakub Jermar, Jakub vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
35,7 → 35,12 |
#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. |
48,6 → 53,23 |
*/ |
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/dynload/kernel/arch/ia64/src/mm/tlb.c |
---|
475,6 → 475,73 |
} |
} |
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 memmaped lagacy io, because |
* of 4KB sized access |
* only for userspace |
* |
* @param va virtual address of page fault |
* @param istate Structure with saved interruption state. |
* |
* |
* @return 1 on success, 0 on fail |
*/ |
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)){ |
//printf("Insert %llX\n",va); |
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; //MUSIM spocitat frame |
entry.ps = USPACE_IO_PAGE_WIDTH; |
dtc_mapping_insert(page, TASK->as->asid, entry); //Musim zjistit ASID |
return 1; |
}else { |
fault_if_from_uspace(istate,"IO access fault at %p",va); |
return 0; |
} |
} else |
return 0; |
else |
return 0; |
return 0; |
} |
/** Data TLB fault handler for faults with VHPT turned off. |
* |
* @param vector Interruption vector. |
511,10 → 578,11 |
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. |
*/ |
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); |
/branches/dynload/kernel/arch/ia64/src/mm/frame.c |
---|
36,14 → 36,20 |
#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_SIZE (256 * 1024 * 1024) |
#define MEMORY_BASE (0 * 64 * 1024 * 1024) |
#define KERNEL_RESERVED_AREA_BASE (0x4400000) |
#define KERNEL_RESERVED_AREA_SIZE (16*1024*1024) |
#define ONE_TO_ONE_MAPPING_SIZE (256*1048576) // Mapped at start |
#define ROM_BASE 0xa0000 //For ski |
50,22 → 56,41 |
#define ROM_SIZE (384 * 1024) //For ski |
void poke_char(int x,int y,char ch, char c); |
#define MIN_ZONE_SIZE (64*1024) |
uintptr_t last_frame; |
#define MINCONF 1 |
void frame_arch_init(void) |
{ |
if(config.cpu_active==1) |
{ |
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0); |
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); |
} |
} |
} |
//zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0); |
/* |
* Blacklist ROM regions. |
*/ |
//frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE)); |
frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE)); |
frame_mark_unavailable(ADDR2PFN(0), SIZE2FRAMES(1048576)); |
last_frame=SIZE2FRAMES((VRN_KERNEL<<VRN_SHIFT)+ONE_TO_ONE_MAPPING_SIZE); |
frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE), SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE)); |
} |
} |
/branches/dynload/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 |
234,19 → 235,19 |
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) |
{ |
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: |
#ifdef CONFIG_DEBUG |
254,12 → 255,60 |
#endif |
break; |
#ifdef CONFIG_SMP |
case VECTOR_TLB_SHOOTDOWN_IPI: |
tlb_shootdown_ipi_recv(); |
end_of_local_irq(); |
break; |
#endif |
case INTERRUPT_TIMER: |
{ |
irq_t *irq = irq_dispatch_and_lock(ivr.vector); |
if (irq) { |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
panic("\nUnhandled Internal Timer Interrupt (%d)\n",ivr.vector); |
} |
} |
break; |
default: |
panic("\nUnhandled External Interrupt Vector %d\n", |
ivr.vector); |
{ |
int ack=false; |
irq_t *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(); |
ack=true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
* Unhandled interrupt. |
*/ |
end_of_local_irq(); |
ack=true; |
#ifdef CONFIG_DEBUG |
printf("\nUnhandled External Interrupt Vector %d\n",ivr.vector); |
#endif |
} |
if(!ack) end_of_local_irq(); |
} |
break; |
} |
} |
} |
/** @} |
/branches/dynload/kernel/arch/ia64/src/drivers/ega.c |
---|
46,12 → 46,18 |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/drivers/ega.h> |
#include <ddi/ddi.h> |
/* |
* The EGA driver. |
* Simple and short. Function for displaying characters and "scrolling". |
*/ |
static parea_t ega_parea; /**< Physical memory area for EGA video RAM. */ |
SPINLOCK_INITIALIZE(egalock); |
static uint32_t ega_cursor; |
static uint8_t *videoram; |
75,12 → 81,21 |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
ega_parea.pbase = VIDEORAM & 0xffffffff; |
ega_parea.vbase = (uintptr_t) videoram; |
ega_parea.frames = 1; |
ega_parea.cacheable = false; |
ddi_parea_register(&ega_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM); |
sysinfo_set_item_val("fb.blinking", NULL, true); |
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM & 0xffffffff); |
#ifndef CONFIG_FB |
putchar('\n'); |