/branches/sparc/kernel/arch/sparc64/include/drivers/pci.h |
---|
51,8 → 51,8 |
}; |
struct pci_operations { |
void (* enable_interrupt)(pci_t *pci, int inr); |
void (* clear_interrupt)(pci_t *pci, int inr); |
void (* enable_interrupt)(pci_t *, int); |
void (* clear_interrupt)(pci_t *, int); |
}; |
struct pci { |
61,9 → 61,9 |
volatile uint64_t *reg; /**< Registers including interrupt registers. */ |
}; |
extern pci_t *pci_init(ofw_tree_node_t *node); |
extern void pci_enable_interrupt(pci_t *pci, int inr); |
extern void pci_clear_interrupt(pci_t *pci, int inr); |
extern pci_t *pci_init(ofw_tree_node_t *); |
extern void pci_enable_interrupt(pci_t *, int); |
extern void pci_clear_interrupt(void *, int); |
#endif |
/branches/sparc/kernel/arch/sparc64/include/drivers/fhc.h |
---|
44,9 → 44,9 |
extern fhc_t *central_fhc; |
extern fhc_t *fhc_init(ofw_tree_node_t *node); |
extern void fhc_enable_interrupt(fhc_t *fhc, int inr); |
extern void fhc_clear_interrupt(fhc_t *fhc, int inr); |
extern fhc_t *fhc_init(ofw_tree_node_t *); |
extern void fhc_enable_interrupt(fhc_t *, int); |
extern void fhc_clear_interrupt(void *, int); |
#endif |
/branches/sparc/kernel/arch/sparc64/src/console.c |
---|
145,16 → 145,27 |
} |
#endif |
#ifdef CONFIG_NS16550 |
#ifdef CONFIG_NS16550_INTERRUPT_DRIVEN |
if (kbd_type == KBD_NS16550) { |
/* |
* The ns16550 driver is interrupt-driven. |
*/ |
return; |
} |
#endif |
#endif |
while (1) { |
#ifdef CONFIG_NS16550 |
#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN |
if (kbd_type == KBD_NS16550) |
ns16550_poll(); |
#endif |
#endif |
#ifdef CONFIG_SGCN |
if (kbd_type == KBD_SGCN) |
sgcn_poll(); |
#endif |
thread_usleep(KEYBOARD_POLL_PAUSE); |
} |
} |
/branches/sparc/kernel/arch/sparc64/src/trap/interrupt.c |
---|
87,6 → 87,12 |
* The IRQ handler was found. |
*/ |
irq->handler(irq, irq->arg); |
/* |
* See if there is a clear-interrupt-routine and call it. |
*/ |
if (irq->cir) { |
irq->cir(irq->cir_arg, irq->inr); |
} |
spinlock_unlock(&irq->lock); |
} else if (data0 > config.base) { |
/* |
/branches/sparc/kernel/arch/sparc64/src/drivers/fhc.c |
---|
101,8 → 101,9 |
} |
} |
void fhc_clear_interrupt(fhc_t *fhc, int inr) |
void fhc_clear_interrupt(void *fhcp, int inr) |
{ |
fhc_t *fhc = (fhc_t *)fhcp; |
ASSERT(fhc->uart_imap); |
switch (inr) { |
/branches/sparc/kernel/arch/sparc64/src/drivers/kbd.c |
---|
63,6 → 63,8 |
uintptr_t aligned_addr; |
ofw_tree_property_t *prop; |
const char *name; |
cir_t cir; |
void *cir_arg; |
name = ofw_tree_node_name(node); |
103,11 → 105,14 |
switch (kbd_type) { |
case KBD_Z8530: |
size = ((ofw_fhc_reg_t *) prop->value)->size; |
if (!ofw_fhc_apply_ranges(node->parent, ((ofw_fhc_reg_t *) prop->value) , &pa)) { |
if (!ofw_fhc_apply_ranges(node->parent, |
((ofw_fhc_reg_t *) prop->value), &pa)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) { |
if (!ofw_fhc_map_interrupt(node->parent, |
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
} |
115,11 → 120,14 |
case KBD_NS16550: |
size = ((ofw_ebus_reg_t *) prop->value)->size; |
if (!ofw_ebus_apply_ranges(node->parent, ((ofw_ebus_reg_t *) prop->value) , &pa)) { |
if (!ofw_ebus_apply_ranges(node->parent, |
((ofw_ebus_reg_t *) prop->value), &pa)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) { |
if (!ofw_ebus_map_interrupt(node->parent, |
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
}; |
142,16 → 150,17 |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_init(devno, inr, vaddr); |
z8530_init(devno, vaddr, inr, cir, cir_arg); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_init(devno, inr, (ioport_t)vaddr); |
ns16550_init(devno, (ioport_t)vaddr, inr, cir, cir_arg); |
break; |
#endif |
default: |
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n"); |
printf("Kernel is not compiled with the necessary keyboard " |
"driver this machine requires.\n"); |
} |
} |
/branches/sparc/kernel/arch/sparc64/src/drivers/pci.c |
---|
45,33 → 45,30 |
#include <func.h> |
#include <arch/asm.h> |
#define PCI_SABRE_REGS_REG 0 |
#define SABRE_INTERNAL_REG 0 |
#define PSYCHO_INTERNAL_REG 2 |
#define PCI_SABRE_IMAP_BASE 0x200 |
#define PCI_SABRE_ICLR_BASE 0x300 |
#define OBIO_IMR_BASE 0x200 |
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK)) |
#define PCI_PSYCHO_REGS_REG 2 |
#define OBIO_CIR_BASE 0x300 |
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK)) |
#define PCI_PSYCHO_IMAP_BASE 0x200 |
#define PCI_PSYCHO_ICLR_BASE 0x300 |
static void obio_enable_interrupt(pci_t *, int); |
static void obio_clear_interrupt(pci_t *, int); |
static pci_t *pci_sabre_init(ofw_tree_node_t *node); |
static void pci_sabre_enable_interrupt(pci_t *pci, int inr); |
static void pci_sabre_clear_interrupt(pci_t *pci, int inr); |
static pci_t *pci_sabre_init(ofw_tree_node_t *); |
static pci_t *pci_psycho_init(ofw_tree_node_t *); |
static pci_t *pci_psycho_init(ofw_tree_node_t *node); |
static void pci_psycho_enable_interrupt(pci_t *pci, int inr); |
static void pci_psycho_clear_interrupt(pci_t *pci, int inr); |
/** PCI operations for Sabre model. */ |
static pci_operations_t pci_sabre_ops = { |
.enable_interrupt = pci_sabre_enable_interrupt, |
.clear_interrupt = pci_sabre_clear_interrupt |
.enable_interrupt = obio_enable_interrupt, |
.clear_interrupt = obio_clear_interrupt |
}; |
/** PCI operations for Psycho model. */ |
static pci_operations_t pci_psycho_ops = { |
.enable_interrupt = pci_psycho_enable_interrupt, |
.clear_interrupt = pci_psycho_clear_interrupt |
.enable_interrupt = obio_enable_interrupt, |
.clear_interrupt = obio_clear_interrupt |
}; |
/** Initialize PCI controller (model Sabre). |
95,11 → 92,12 |
ofw_upa_reg_t *reg = prop->value; |
count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
if (regs < PCI_SABRE_REGS_REG + 1) |
if (regs < SABRE_INTERNAL_REG + 1) |
return NULL; |
uintptr_t paddr; |
if (!ofw_upa_apply_ranges(node->parent, ®[PCI_SABRE_REGS_REG], &paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[SABRE_INTERNAL_REG], |
&paddr)) |
return NULL; |
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC); |
108,7 → 106,7 |
pci->model = PCI_SABRE; |
pci->op = &pci_sabre_ops; |
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_SABRE_REGS_REG].size); |
pci->reg = (uint64_t *) hw_map(paddr, reg[SABRE_INTERNAL_REG].size); |
return pci; |
} |
135,11 → 133,12 |
ofw_upa_reg_t *reg = prop->value; |
count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
if (regs < PCI_PSYCHO_REGS_REG + 1) |
if (regs < PSYCHO_INTERNAL_REG + 1) |
return NULL; |
uintptr_t paddr; |
if (!ofw_upa_apply_ranges(node->parent, ®[PCI_PSYCHO_REGS_REG], &paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[PSYCHO_INTERNAL_REG], |
&paddr)) |
return NULL; |
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC); |
148,31 → 147,21 |
pci->model = PCI_PSYCHO; |
pci->op = &pci_psycho_ops; |
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_PSYCHO_REGS_REG].size); |
pci->reg = (uint64_t *) hw_map(paddr, reg[PSYCHO_INTERNAL_REG].size); |
return pci; |
} |
void pci_sabre_enable_interrupt(pci_t *pci, int inr) |
void obio_enable_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[PCI_SABRE_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK; |
pci->reg[OBIO_IMR(inr & INO_MASK)] |= IMAP_V_MASK; |
} |
void pci_sabre_clear_interrupt(pci_t *pci, int inr) |
void obio_clear_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[PCI_SABRE_ICLR_BASE + (inr & INO_MASK)] = 0; |
pci->reg[OBIO_CIR(inr & INO_MASK)] = 0; /* set IDLE */ |
} |
void pci_psycho_enable_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[PCI_PSYCHO_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK; |
} |
void pci_psycho_clear_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[PCI_PSYCHO_ICLR_BASE + (inr & INO_MASK)] = 0; |
} |
/** Initialize PCI controller. */ |
pci_t *pci_init(ofw_tree_node_t *node) |
{ |
215,14 → 204,14 |
void pci_enable_interrupt(pci_t *pci, int inr) |
{ |
ASSERT(pci->model); |
ASSERT(pci->op && pci->op->enable_interrupt); |
pci->op->enable_interrupt(pci, inr); |
} |
void pci_clear_interrupt(pci_t *pci, int inr) |
void pci_clear_interrupt(void *pcip, int inr) |
{ |
ASSERT(pci->model); |
pci_t *pci = (pci_t *)pcip; |
ASSERT(pci->op && pci->op->clear_interrupt); |
pci->op->clear_interrupt(pci, inr); |
} |
/branches/sparc/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+LAGACY_INTERRUPT_BASE) |
#define IRQ_MOUSE (0x0c+LAGACY_INTERRUPT_BASE) |
#define INTERRUPT_SPURIOUS 15 |
#define LAGACY_INTERRUPT_BASE 0x20 |
/** General Exception codes. */ |
#define GE_ILLEGALOP 0 |
150,6 → 153,7 |
extern void external_interrupt(uint64_t vector, istate_t *istate); |
extern void disabled_fp_register(uint64_t vector, istate_t *istate); |
#endif |
/** @} |
/branches/sparc/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/sparc/kernel/arch/ia64/include/bootinfo.h |
---|
33,6 → 33,13 |
#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 |
typedef struct { |
void *addr; |
unsigned long size; |
43,14 → 50,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; |
/branches/sparc/kernel/arch/ia64/include/mm/page.h |
---|
48,8 → 48,15 |
#define IO_PAGE_WIDTH 26 /* 64M */ |
#define FW_PAGE_WIDTH 28 /* 256M */ |
/** Staticly mapped IO spaces */ |
#define USPACE_IO_PAGE_WIDTH 12 /* 4K */ |
/** Staticly mapped IO spaces - offsets to 0xe...00 of virtual adresses |
becauce of "minimal virtual bits implemented is 51" |
it is possible to have here values up to 0x0007000000000000 |
*/ |
/* Firmware area (bellow 4GB in phys mem) */ |
#define FW_OFFSET 0x00000000F0000000 |
/* Legacy IO space */ |
/branches/sparc/kernel/arch/ia64/include/mm/tlb.h |
---|
46,8 → 46,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/sparc/kernel/arch/ia64/include/cpu.h |
---|
87,6 → 87,8 |
static inline void ipi_send_ipi(int id,int eid,int intno) |
{ |
(bootinfo->sapic)[2*(id*256+eid)]=intno; |
srlz_d(); |
} |
/branches/sparc/kernel/arch/ia64/include/drivers/kbd.h |
---|
0,0 → 1,48 |
/* |
* 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/sparc/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(); |
122,6 → 155,7 |
#endif |
} |
it_init(); |
} |
void arch_post_cpu_init(void) |
139,15 → 173,28 |
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); |
} |
} |
#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,7 → 287,13 |
{ |
#ifdef SKI |
ski_kbd_grab(); |
#else |
#ifdef CONFIG_NS16550 |
ns16550_grab(); |
#else |
i8042_grab(); |
#endif |
#endif |
} |
/** Return console to userspace |
* |
240,7 → 302,14 |
{ |
#ifdef SKI |
ski_kbd_release(); |
#else |
#ifdef CONFIG_NS16550 |
ns16550_release(); |
#else |
i8042_release(); |
#endif |
#endif |
} |
void arch_reboot(void) |
/branches/sparc/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/sparc/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/sparc/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/sparc/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/sparc/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/sparc/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,13 → 255,61 |
#endif |
break; |
default: |
panic("\nUnhandled External Interrupt Vector %d\n", |
ivr.vector); |
#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: |
{ |
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/sparc/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; |
76,11 → 82,20 |
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'); |
/branches/sparc/kernel/arch/ia32/src/asm.S |
---|
158,6 → 158,7 |
*/ |
.global sysenter_handler |
sysenter_handler: |
sti |
pushl %ebp # remember user stack |
pushl %edi # remember return user address |