Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1908 → Rev 1909

/trunk/kernel/arch/sparc64/src/drivers/fhc.c
41,30 → 41,81
 
#include <arch/drivers/fhc.h>
#include <arch/mm/page.h>
#include <mm/slab.h>
#include <arch/types.h>
#include <typedefs.h>
 
#include <genarch/ofw/ofw_tree.h>
#include <genarch/kbd/z8530.h>
 
volatile uint32_t *fhc = NULL;
fhc_t *central_fhc = NULL;
 
#define FHC_UART_ADDR 0x1fff8808000ULL /* hardcoded for Simics simulation */
/**
* I suspect this must be hardcoded in the FHC.
* If it is not, than we can read all IMAP registers
* and get the complete mapping.
*/
#define FHC_UART_INO 0x39
 
#define FHC_UART_IMAP 0x0
#define FHC_UART_ICLR 0x4
 
void fhc_init(void)
#define UART_IMAP_REG 4
 
fhc_t *fhc_init(ofw_tree_node_t *node)
{
fhc = (void *) hw_map(FHC_UART_ADDR, PAGE_SIZE);
fhc_t *fhc;
ofw_tree_property_t *prop;
 
fhc[FHC_UART_ICLR] = 0;
fhc[FHC_UART_IMAP] = 0x80000000;
prop = ofw_tree_getprop(node, "reg");
if (!prop || !prop->value)
return NULL;
count_t regs = prop->size / sizeof(ofw_central_reg_t);
if (regs + 1 < UART_IMAP_REG)
return NULL;
 
ofw_central_reg_t *reg = &((ofw_central_reg_t *) prop->value)[UART_IMAP_REG];
 
uintptr_t paddr;
if (!ofw_central_apply_ranges(node->parent, reg, &paddr))
return NULL;
 
fhc = (fhc_t *) malloc(sizeof(fhc_t), FRAME_ATOMIC);
if (!fhc)
return NULL;
 
fhc->uart_imap = (uint32_t *) hw_map(paddr, reg->size);
return fhc;
}
 
void fhc_uart_reset(void)
void fhc_enable_interrupt(fhc_t *fhc, int ino)
{
fhc[FHC_UART_ICLR] = 0;
switch (ino) {
case FHC_UART_INO:
fhc->uart_imap[FHC_UART_ICLR] = 0x0;
fhc->uart_imap[FHC_UART_IMAP] = 0x80000000;
break;
default:
panic("Unexpected INO (%d)\n", ino);
break;
}
}
 
void fhc_clear_interrupt(fhc_t *fhc, int ino)
{
ASSERT(fhc->uart_imap);
 
switch (ino) {
case FHC_UART_INO:
fhc->uart_imap[FHC_UART_ICLR] = 0;
break;
default:
panic("Unexpected INO (%d)\n", ino);
break;
}
}
 
/** @}
*/
/trunk/kernel/arch/sparc64/src/drivers/kbd.c
68,6 → 68,9
name = ofw_tree_node_name(node);
/*
* Determine keyboard serial controller type.
*/
if (strcmp(name, "zs") == 0)
kbd_type = KBD_Z8530;
else if (strcmp(name, "su") == 0)
78,12 → 81,25
return;
}
/*
* Read 'interrupts' property.
*/
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);
 
/*
* Read 'reg' property.
*/
prop = ofw_tree_getprop(node, "reg");
if (!prop)
if (!prop || !prop->value)
panic("Can't find \"reg\" property.\n");
uintptr_t pa;
size_t size;
int ino;
switch (kbd_type) {
case KBD_Z8530:
92,6 → 108,10
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_fhc_map_interrupts(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &ino)) {
printf("Failed to determine keyboard interrupts.\n");
return;
}
break;
case KBD_NS16550:
size = ((ofw_ebus_reg_t *) prop->value)->size;
99,6 → 119,10
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_ebus_map_interrupts(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &ino)) {
printf("Failed to determine keyboard interrupts.\n");
return;
}
break;
default:
panic("Unexpected type.\n");