/trunk/kernel/arch/sparc64/src/drivers/sgcn.c |
---|
File deleted |
/trunk/kernel/arch/sparc64/src/drivers/scr.c |
---|
37,7 → 37,7 |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <arch/types.h> |
#include <string.h> |
#include <func.h> |
#include <align.h> |
#include <print.h> |
55,30 → 55,23 |
void scr_init(ofw_tree_node_t *node) |
{ |
ofw_tree_property_t *prop; |
ofw_pci_reg_t *pci_reg; |
ofw_pci_reg_t pci_abs_reg; |
ofw_upa_reg_t *upa_reg; |
ofw_sbus_reg_t *sbus_reg; |
const char *name; |
name = ofw_tree_node_name(node); |
if (str_cmp(name, "SUNW,m64B") == 0) |
if (strcmp(name, "SUNW,m64B") == 0) |
scr_type = SCR_ATYFB; |
else if (str_cmp(name, "SUNW,XVR-100") == 0) |
scr_type = SCR_XVR; |
else if (str_cmp(name, "SUNW,ffb") == 0) |
else if (strcmp(name, "SUNW,ffb") == 0) |
scr_type = SCR_FFB; |
else if (str_cmp(name, "cgsix") == 0) |
else if (strcmp(name, "cgsix") == 0) |
scr_type = SCR_CGSIX; |
if (scr_type == SCR_UNKNOWN) { |
printf("Unknown screen device.\n"); |
printf("Unknown keyboard device.\n"); |
return; |
} |
uintptr_t fb_addr; |
unsigned int fb_offset = 0; |
uint32_t fb_width = 0; |
uint32_t fb_height = 0; |
uint32_t fb_depth = 0; |
104,7 → 97,7 |
prop = ofw_tree_getprop(node, "reg"); |
if (!prop) |
panic("Cannot find 'reg' property."); |
panic("Can't find \"reg\" property.\n"); |
switch (scr_type) { |
case SCR_ATYFB: |
113,15 → 106,15 |
return; |
} |
pci_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
ofw_pci_reg_t *fb_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
ofw_pci_reg_t abs_reg; |
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) { |
if (!ofw_pci_reg_absolutize(node, fb_reg, &abs_reg)) { |
printf("Failed to absolutize fb register.\n"); |
return; |
} |
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg, |
&fb_addr)) { |
if (!ofw_pci_apply_ranges(node->parent, &abs_reg , &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
133,11 → 126,11 |
break; |
case 16: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_5_6_5_BE; |
visual = VISUAL_RGB_5_6_5; |
break; |
case 24: |
fb_scanline = fb_linebytes * 4; |
visual = VISUAL_BGR_8_8_8_0; |
visual = VISUAL_RGB_8_8_8_0; |
break; |
case 32: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
149,56 → 142,12 |
} |
break; |
case SCR_XVR: |
if (prop->size / sizeof(ofw_pci_reg_t) < 2) { |
printf("Too few screen registers.\n"); |
return; |
} |
pci_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) { |
printf("Failed to absolutize fb register.\n"); |
return; |
} |
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg, |
&fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
fb_offset = 4 * 0x2000; |
switch (fb_depth) { |
case 8: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_5_6_5_BE; |
break; |
case 24: |
fb_scanline = fb_linebytes * 4; |
visual = VISUAL_BGR_8_8_8_0; |
break; |
case 32: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
printf("Unsupported bits per pixel.\n"); |
return; |
} |
break; |
case SCR_FFB: |
fb_scanline = 8192; |
visual = VISUAL_BGR_0_8_8_8; |
upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP]; |
if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) { |
ofw_upa_reg_t *reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP]; |
if (!ofw_upa_apply_ranges(node->parent, reg, &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
215,8 → 164,8 |
return; |
} |
sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0]; |
if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) { |
ofw_sbus_reg_t *cg6_reg = &((ofw_sbus_reg_t *) prop->value)[0]; |
if (!ofw_sbus_apply_ranges(node->parent, cg6_reg, &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
223,24 → 172,11 |
break; |
default: |
panic("Unexpected type."); |
panic("Unexpected type.\n"); |
} |
fb_properties_t props = { |
.addr = fb_addr, |
.offset = fb_offset, |
.x = fb_width, |
.y = fb_height, |
.scan = fb_scanline, |
.visual = visual, |
}; |
fb_init(&props); |
fb_init(fb_addr, fb_width, fb_height, fb_scanline, visual); |
} |
void scr_redraw(void) |
{ |
fb_redraw(); |
} |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/src/drivers/tick.c |
---|
45,12 → 45,11 |
#define TICK_RESTART_TIME 50 /* Worst case estimate. */ |
/** Initialize tick and stick interrupt. */ |
/** Initialize tick interrupt. */ |
void tick_init(void) |
{ |
/* initialize TICK interrupt */ |
tick_compare_reg_t compare; |
interrupt_register(14, "tick_int", tick_interrupt); |
compare.int_dis = false; |
compare.tick_cmpr = CPU->arch.clock_frequency / HZ; |
57,21 → 56,6 |
CPU->arch.next_tick_cmpr = compare.tick_cmpr; |
tick_compare_write(compare.value); |
tick_write(0); |
#if defined (US3) |
/* disable STICK interrupts and clear any pending ones */ |
tick_compare_reg_t stick_compare; |
softint_reg_t clear; |
stick_compare.value = stick_compare_read(); |
stick_compare.int_dis = true; |
stick_compare.tick_cmpr = 0; |
stick_compare_write(stick_compare.value); |
clear.value = 0; |
clear.stick_int = 1; |
clear_softint_write(clear.value); |
#endif |
} |
/** Process tick interrupt. |
83,7 → 67,7 |
{ |
softint_reg_t softint, clear; |
uint64_t drift; |
softint.value = softint_read(); |
/* |
/trunk/kernel/arch/sparc64/src/drivers/fhc.c |
---|
45,7 → 45,6 |
#include <mm/slab.h> |
#include <arch/types.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <sysinfo/sysinfo.h> |
fhc_t *central_fhc = NULL; |
71,7 → 70,7 |
if (!prop || !prop->value) |
return NULL; |
size_t regs = prop->size / sizeof(ofw_central_reg_t); |
count_t regs = prop->size / sizeof(ofw_central_reg_t); |
if (regs + 1 < UART_IMAP_REG) |
return NULL; |
87,13 → 86,6 |
fhc->uart_imap = (uint32_t *) hw_map(paddr, reg->size); |
/* |
* Set sysinfo data needed by the uspace FHC driver. |
*/ |
sysinfo_set_item_val("fhc.uart.size", NULL, reg->size); |
sysinfo_set_item_val("fhc.uart.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.fhc", NULL, 1); |
return fhc; |
} |
104,14 → 96,13 |
fhc->uart_imap[FHC_UART_IMAP] |= IMAP_V_MASK; |
break; |
default: |
panic("Unexpected INR (%d).", inr); |
panic("Unexpected INR (%d)\n", inr); |
break; |
} |
} |
void fhc_clear_interrupt(void *fhcp, int inr) |
void fhc_clear_interrupt(fhc_t *fhc, int inr) |
{ |
fhc_t *fhc = (fhc_t *)fhcp; |
ASSERT(fhc->uart_imap); |
switch (inr) { |
119,7 → 110,7 |
fhc->uart_imap[FHC_UART_ICLR] = 0; |
break; |
default: |
panic("Unexpected INR (%d).", inr); |
panic("Unexpected INR (%d)\n", inr); |
break; |
} |
} |
/trunk/kernel/arch/sparc64/src/drivers/kbd.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
34,160 → 34,99 |
#include <arch/drivers/kbd.h> |
#include <genarch/ofw/ofw_tree.h> |
#ifdef CONFIG_SUN_KBD |
#include <genarch/kbrd/kbrd.h> |
#endif |
#ifdef CONFIG_Z8530 |
#include <genarch/drivers/z8530/z8530.h> |
#include <genarch/kbd/z8530.h> |
#endif |
#ifdef CONFIG_NS16550 |
#include <genarch/drivers/ns16550/ns16550.h> |
#include <genarch/kbd/ns16550.h> |
#endif |
#include <console/console.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <arch/mm/page.h> |
#include <arch/types.h> |
#include <align.h> |
#include <string.h> |
#include <func.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
#ifdef CONFIG_SUN_KBD |
kbd_type_t kbd_type = KBD_UNKNOWN; |
#ifdef CONFIG_Z8530 |
static bool kbd_z8530_init(ofw_tree_node_t *node) |
/** Initialize keyboard. |
* |
* Traverse OpenFirmware device tree in order to find necessary |
* info about the keyboard device. |
* |
* @param node Keyboard device node. |
*/ |
void kbd_init(ofw_tree_node_t *node) |
{ |
const char *name = ofw_tree_node_name(node); |
size_t offset; |
uintptr_t aligned_addr; |
ofw_tree_property_t *prop; |
const char *name; |
if (str_cmp(name, "zs") != 0) |
return false; |
name = ofw_tree_node_name(node); |
/* |
* Read 'interrupts' property. |
* Determine keyboard serial controller type. |
*/ |
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts"); |
if ((!prop) || (!prop->value)) { |
printf("z8530: Unable to find interrupts property\n"); |
return false; |
} |
if (strcmp(name, "zs") == 0) |
kbd_type = KBD_Z8530; |
else if (strcmp(name, "su") == 0) |
kbd_type = KBD_NS16550; |
uint32_t interrupts = *((uint32_t *) prop->value); |
/* |
* Read 'reg' property. |
*/ |
prop = ofw_tree_getprop(node, "reg"); |
if ((!prop) || (!prop->value)) { |
printf("z8530: Unable to find reg property\n"); |
return false; |
if (kbd_type == KBD_UNKNOWN) { |
printf("Unknown keyboard device.\n"); |
return; |
} |
size_t size = ((ofw_fhc_reg_t *) prop->value)->size; |
uintptr_t pa; |
if (!ofw_fhc_apply_ranges(node->parent, |
((ofw_fhc_reg_t *) prop->value), &pa)) { |
printf("z8530: Failed to determine address\n"); |
return false; |
} |
inr_t inr; |
cir_t cir; |
void *cir_arg; |
if (!ofw_fhc_map_interrupt(node->parent, |
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("z8530: Failed to determine interrupt\n"); |
return false; |
} |
/* |
* We need to pass aligned address to hw_map(). |
* However, the physical keyboard address can |
* be pretty much unaligned, depending on the |
* underlying controller. |
* Read 'interrupts' property. |
*/ |
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
size_t offset = pa - aligned_addr; |
z8530_t *z8530 = (z8530_t *) |
(hw_map(aligned_addr, offset + size) + offset); |
z8530_instance_t *z8530_instance = z8530_init(z8530, inr, cir, cir_arg); |
if (z8530_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
z8530_wire(z8530_instance, kbrd); |
} |
} |
/* |
* This is the necessary evil until the userspace drivers are |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) z8530); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
sysinfo_set_item_val("kbd.type.z8530", NULL, true); |
return true; |
} |
uint32_t interrupts; |
prop = ofw_tree_getprop(node, "interrupts"); |
if (!prop || !prop->value) |
panic("Can't find \"interrupts\" property.\n"); |
interrupts = *((uint32_t *) prop->value); |
#endif /* CONFIG_Z8530 */ |
#ifdef CONFIG_NS16550 |
static bool kbd_ns16550_init(ofw_tree_node_t *node) |
{ |
const char *name = ofw_tree_node_name(node); |
if (str_cmp(name, "su") != 0) |
return false; |
/* |
* Read 'interrupts' property. |
*/ |
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts"); |
if ((!prop) || (!prop->value)) { |
printf("ns16550: Unable to find interrupts property\n"); |
return false; |
} |
uint32_t interrupts = *((uint32_t *) prop->value); |
/* |
* Read 'reg' property. |
*/ |
prop = ofw_tree_getprop(node, "reg"); |
if ((!prop) || (!prop->value)) { |
printf("ns16550: Unable to find reg property\n"); |
return false; |
} |
if (!prop || !prop->value) |
panic("Can't find \"reg\" property.\n"); |
size_t size = ((ofw_ebus_reg_t *) prop->value)->size; |
uintptr_t pa; |
if (!ofw_ebus_apply_ranges(node->parent, |
((ofw_ebus_reg_t *) prop->value), &pa)) { |
printf("ns16550: Failed to determine address\n"); |
return false; |
} |
size_t size; |
inr_t inr; |
devno_t devno = device_assign_devno(); |
inr_t inr; |
cir_t cir; |
void *cir_arg; |
if (!ofw_ebus_map_interrupt(node->parent, |
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("ns16550: Failed to determine interrupt\n"); |
return false; |
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)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
} |
break; |
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)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
}; |
break; |
default: |
panic("Unexpected type.\n"); |
} |
/* |
196,58 → 135,25 |
* be pretty much unaligned, depending on the |
* underlying controller. |
*/ |
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
size_t offset = pa - aligned_addr; |
ns16550_t *ns16550 = (ns16550_t *) |
(hw_map(aligned_addr, offset + size) + offset); |
ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, inr, cir, cir_arg); |
if (ns16550_instance) { |
kbrd_instance_t *kbrd_instance = kbrd_init(); |
if (kbrd_instance) { |
indev_t *sink = stdin_wire(); |
indev_t *kbrd = kbrd_wire(kbrd_instance, sink); |
ns16550_wire(ns16550_instance, kbrd); |
} |
} |
/* |
* This is the necessary evil until the userspace drivers are |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) ns16550); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
sysinfo_set_item_val("kbd.type.ns16550", NULL, true); |
return true; |
} |
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
offset = pa - aligned_addr; |
uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset; |
#endif /* CONFIG_NS16550 */ |
/** Initialize keyboard. |
* |
* Traverse OpenFirmware device tree in order to find necessary |
* info about the keyboard device. |
* |
* @param node Keyboard device node. |
* |
*/ |
void kbd_init(ofw_tree_node_t *node) |
{ |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
kbd_z8530_init(node); |
case KBD_Z8530: |
z8530_init(devno, inr, vaddr); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
kbd_ns16550_init(node); |
case KBD_NS16550: |
ns16550_init(devno, inr, vaddr); |
break; |
#endif |
default: |
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n"); |
} |
} |
#endif /* CONFIG_SUN_KBD */ |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/src/drivers/pci.c |
---|
42,41 → 42,43 |
#include <arch/types.h> |
#include <debug.h> |
#include <print.h> |
#include <string.h> |
#include <func.h> |
#include <arch/asm.h> |
#include <sysinfo/sysinfo.h> |
#define SABRE_INTERNAL_REG 0 |
#define PSYCHO_INTERNAL_REG 2 |
#define PCI_SABRE_REGS_REG 0 |
#define OBIO_IMR_BASE 0x200 |
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK)) |
#define PCI_SABRE_IMAP_BASE 0x200 |
#define PCI_SABRE_ICLR_BASE 0x300 |
#define OBIO_CIR_BASE 0x300 |
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK)) |
#define PCI_PSYCHO_REGS_REG 2 |
static void obio_enable_interrupt(pci_t *, int); |
static void obio_clear_interrupt(pci_t *, int); |
#define PCI_PSYCHO_IMAP_BASE 0x200 |
#define PCI_PSYCHO_ICLR_BASE 0x300 |
static pci_t *pci_sabre_init(ofw_tree_node_t *); |
static pci_t *pci_psycho_init(ofw_tree_node_t *); |
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_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 = obio_enable_interrupt, |
.clear_interrupt = obio_clear_interrupt |
.enable_interrupt = pci_sabre_enable_interrupt, |
.clear_interrupt = pci_sabre_clear_interrupt |
}; |
/** PCI operations for Psycho model. */ |
static pci_operations_t pci_psycho_ops = { |
.enable_interrupt = obio_enable_interrupt, |
.clear_interrupt = obio_clear_interrupt |
.enable_interrupt = pci_psycho_enable_interrupt, |
.clear_interrupt = pci_psycho_clear_interrupt |
}; |
/** Initialize PCI controller (model Sabre). |
* |
* @param node OpenFirmware device tree node of the Sabre. |
* @param node OpenFirmware device tree node of the Sabre. |
* |
* @return Address of the initialized PCI structure. |
* @return Address of the initialized PCI structure. |
*/ |
pci_t *pci_sabre_init(ofw_tree_node_t *node) |
{ |
91,14 → 93,13 |
return NULL; |
ofw_upa_reg_t *reg = prop->value; |
size_t regs = prop->size / sizeof(ofw_upa_reg_t); |
count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
if (regs < SABRE_INTERNAL_REG + 1) |
if (regs < PCI_SABRE_REGS_REG + 1) |
return NULL; |
uintptr_t paddr; |
if (!ofw_upa_apply_ranges(node->parent, ®[SABRE_INTERNAL_REG], |
&paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[PCI_SABRE_REGS_REG], &paddr)) |
return NULL; |
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC); |
107,14 → 108,8 |
pci->model = PCI_SABRE; |
pci->op = &pci_sabre_ops; |
pci->reg = (uint64_t *) hw_map(paddr, reg[SABRE_INTERNAL_REG].size); |
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_SABRE_REGS_REG].size); |
/* |
* Set sysinfo data needed by the uspace OBIO driver. |
*/ |
sysinfo_set_item_val("obio.base.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.obio", NULL, 1); |
return pci; |
} |
121,9 → 116,9 |
/** Initialize the Psycho PCI controller. |
* |
* @param node OpenFirmware device tree node of the Psycho. |
* @param node OpenFirmware device tree node of the Psycho. |
* |
* @return Address of the initialized PCI structure. |
* @return Address of the initialized PCI structure. |
*/ |
pci_t *pci_psycho_init(ofw_tree_node_t *node) |
{ |
138,14 → 133,13 |
return NULL; |
ofw_upa_reg_t *reg = prop->value; |
size_t regs = prop->size / sizeof(ofw_upa_reg_t); |
count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
if (regs < PSYCHO_INTERNAL_REG + 1) |
if (regs < PCI_PSYCHO_REGS_REG + 1) |
return NULL; |
uintptr_t paddr; |
if (!ofw_upa_apply_ranges(node->parent, ®[PSYCHO_INTERNAL_REG], |
&paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[PCI_PSYCHO_REGS_REG], &paddr)) |
return NULL; |
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC); |
154,27 → 148,31 |
pci->model = PCI_PSYCHO; |
pci->op = &pci_psycho_ops; |
pci->reg = (uint64_t *) hw_map(paddr, reg[PSYCHO_INTERNAL_REG].size); |
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_PSYCHO_REGS_REG].size); |
/* |
* Set sysinfo data needed by the uspace OBIO driver. |
*/ |
sysinfo_set_item_val("obio.base.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.obio", NULL, 1); |
return pci; |
} |
void obio_enable_interrupt(pci_t *pci, int inr) |
void pci_sabre_enable_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[OBIO_IMR(inr & INO_MASK)] |= IMAP_V_MASK; |
pci->reg[PCI_SABRE_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK; |
} |
void obio_clear_interrupt(pci_t *pci, int inr) |
void pci_sabre_clear_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[OBIO_CIR(inr & INO_MASK)] = 0; /* set IDLE */ |
pci->reg[PCI_SABRE_ICLR_BASE + (inr & INO_MASK)] = 0; |
} |
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) |
{ |
183,7 → 181,7 |
/* |
* First, verify this is a PCI node. |
*/ |
ASSERT(str_cmp(ofw_tree_node_name(node), "pci") == 0); |
ASSERT(strcmp(ofw_tree_node_name(node), "pci") == 0); |
/* |
* Determine PCI controller model. |
192,13 → 190,13 |
if (!prop || !prop->value) |
return NULL; |
if (str_cmp(prop->value, "SUNW,sabre") == 0) { |
if (strcmp(prop->value, "SUNW,sabre") == 0) { |
/* |
* PCI controller Sabre. |
* This model is found on UltraSPARC IIi based machines. |
*/ |
return pci_sabre_init(node); |
} else if (str_cmp(prop->value, "SUNW,psycho") == 0) { |
} else if (strcmp(prop->value, "SUNW,psycho") == 0) { |
/* |
* PCI controller Psycho. |
* Used on UltraSPARC II based processors, for instance, |
217,14 → 215,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(void *pcip, int inr) |
void pci_clear_interrupt(pci_t *pci, int inr) |
{ |
pci_t *pci = (pci_t *)pcip; |
ASSERT(pci->model); |
ASSERT(pci->op && pci->op->clear_interrupt); |
pci->op->clear_interrupt(pci, inr); |
} |