Added ISA bus manager written by Thomas Kurschel. This is currently

hard coded to use the ISA IDE driver only.
This bus manager is architecture dependent; maybe there is a better
place to live for it than here. x86 and PPC/Pegasos will have an
ISA bus later - this module only supports x86 for now.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7777 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-06-07 01:05:26 +00:00
parent 1450572a5d
commit de021f71fb
3 changed files with 273 additions and 0 deletions
@@ -0,0 +1,8 @@
SubDir OBOS_TOP src add-ons kernel bus_managers isa ;
UsePrivateHeaders kernel ;
KernelAddon isa : kernel bus_managers :
isa.c
;
@@ -0,0 +1,31 @@
#ifndef _I386_IO_H
#define _I386_IO_H
#define out8(value,port) \
__asm__ ("outb %%al,%%dx"::"a" (value),"d" (port))
#define out16(value,port) \
__asm__ ("outw %%ax,%%dx"::"a" (value),"d" (port))
#define out32(value,port) \
__asm__ ("outl %%eax,%%dx"::"a" (value),"d" (port))
#define in8(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \
_v; \
})
#define in16(port) ({ \
unsigned short _v; \
__asm__ volatile ("inw %%dx,%%ax":"=a" (_v):"d" (port)); \
_v; \
})
#define in32(port) ({ \
unsigned int _v; \
__asm__ volatile ("inl %%dx,%%eax":"=a" (_v):"d" (port)); \
_v; \
})
#endif
+234
View File
@@ -0,0 +1,234 @@
/*
** Copyright 2002/03, Thomas Kurschel. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
/*
ISA bus manager
Implementation.
*/
#include <bus/ISA.h>
#include <KernelExport.h>
#include <device_manager.h>
#include <stdlib.h>
#include <string.h>
//#define TRACE_ISA
#ifdef TRACE_ISA
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
// ToDo: this is architecture dependent and should be made differently!
#include "i386_io.h"
#define ISA_MODULE_NAME "bus_managers/isa/root"
device_manager_info *pnp;
static uint8
isa_read_io_8(int mapped_io_addr)
{
uint8 value = in8(mapped_io_addr);
TRACE(("isa_read8(%x->%x)\n", mapped_io_addr, value));
return value;
}
static void
isa_write_io_8(int mapped_io_addr, uint8 value)
{
TRACE(("isa_write8(%x->%x)\n", value, mapped_io_addr));
out8(value, mapped_io_addr);
}
static uint16
isa_read_io_16(int mapped_io_addr)
{
return in16(mapped_io_addr);
}
static void
isa_write_io_16(int mapped_io_addr, uint16 value)
{
out16(value, mapped_io_addr);
}
static uint32
isa_read_io_32(int mapped_io_addr)
{
return in32(mapped_io_addr);
}
static void
isa_write_io_32(int mapped_io_addr, uint32 value)
{
out32(value, mapped_io_addr);
}
static void *
ram_address(const void *physical_address_in_system_memory)
{
// this is what the BeOS kernel does
return (void *)physical_address_in_system_memory;
}
static status_t
start_isa_dma(long channel, void *buf, long transfer_count,
uchar mode, uchar e_mode)
{
// TBD
// ToDo
return B_NOT_ALLOWED;
}
#if 0
static status_t
lock_isa_dma_channel(long channel)
{
// TBD
// ToDo
return B_NOT_ALLOWED;
}
static status_t
unlock_isa_dma_channel(long channel)
{
// TBD
// ToDo
return B_ERROR;
}
#endif
static status_t
isa_init_device(pnp_node_handle node, void *user_cookie, void **cookie)
{
*cookie = NULL;
return B_OK;
}
static status_t
isa_uninit_device(void *cookie)
{
return B_OK;
}
static status_t
isa_device_added(pnp_node_handle parent)
{
static const pnp_node_attr attrs[] = {
// info about ourself
{ PNP_DRIVER_DRIVER, B_STRING_TYPE, { string: ISA_MODULE_NAME }},
{ PNP_DRIVER_TYPE, B_STRING_TYPE, { string: ISA_DEVICE_TYPE_NAME }},
// unique connection
{ PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "ISA" }},
// mark as being a bus
{ PNP_BUS_IS_BUS, B_UINT8_TYPE, { ui8: 1 }},
// tell where to look for consumers
// ToDo: temporary hack to get things started!
{ PNP_DRIVER_FIXED_CONSUMER, B_STRING_TYPE, { string: "busses/ide/ide_isa/isa/device/v1" }},
{ PNP_DRIVER_DYNAMIC_CONSUMER, B_STRING_TYPE, { string: ISA_DRIVERS_DIR "/" }},
{ NULL }
};
pnp_node_handle node;
char *parent_type;
status_t res;
// make sure parent is really pnp root
if (pnp->get_attr_string( parent, PNP_DRIVER_TYPE, &parent_type, false))
return B_ERROR;
if (strcmp(parent_type, "pnp/root")) {
free(parent_type);
return B_ERROR;
}
free(parent_type);
res = pnp->register_device(parent, attrs, NULL, &node);
if (res != B_OK)
return res;
return B_OK;
}
static status_t
std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
default:
return B_ERROR;
}
}
module_dependency module_dependencies[] = {
{ DEVICE_MANAGER_MODULE_NAME, (module_info **)&pnp },
{}
};
isa2_module_info isa_interface = {
{
{
{
ISA_MODULE_NAME,
0,
std_ops
},
isa_init_device,
isa_uninit_device,
isa_device_added,
NULL
},
// this rescan(); as ISA relies on device drivers to detect their
// devices themselves, we don't have an universal rescan method
NULL
},
isa_read_io_8, isa_write_io_8,
isa_read_io_16, isa_write_io_16,
isa_read_io_32, isa_write_io_32,
ram_address,
start_isa_dma,
};
#if !_BUILDING_kernel && !BOOT
_EXPORT
module_info *modules[] = {
(module_info *)&isa_interface,
NULL
};
#endif