freebsd compat. layer: added freebsd's busdma implementation. we are still missing MII and the ifp/ether methods.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20994 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-05-03 14:14:12 +00:00
parent a0062874c5
commit ac156738e9
13 changed files with 1535 additions and 54 deletions

View File

@ -9,6 +9,7 @@ SubDirCcFlags [ FDefines _KERNEL=1 ] ;
Library libfreebsd_network.a :
bus.c
busdma_machdep.c
compat.c
device.c
if_media.c

View File

@ -15,11 +15,21 @@
#include <compat/dev/pci/pcivar.h>
#include <compat/machine/resource.h>
#include <compat/sys/bus.h>
#include <compat/sys/rman.h>
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
struct resource {
int type;
bus_space_tag_t tag;
bus_space_handle_t handle;
area_id mapped_area;
};
struct internal_intr {
driver_intr_t handler;
void *arg;
@ -47,56 +57,107 @@ map_mem(void **virtualAddr, void *_phy, size_t size, uint32 protection,
}
/* straight from Marcus' ipro1000 driver */
static int
bus_alloc_irq_resource(device_t dev, struct resource *res)
{
uint8 irq = pci_read_config(dev, PCI_interrupt_line, 1);
if (irq == 0 || irq == 0xff)
return -1;
/* XXX */
res->tag = 0;
res->handle = irq;
return 0;
}
static int
bus_alloc_mem_resource(device_t dev, struct resource *res, int regid)
{
uint32 addr = pci_read_config(dev, regid, 4) & PCI_address_memory_32_mask;
uint32 size = 128 * 1024; /* XXX */
void *virtualAddr;
res->mapped_area = map_mem(&virtualAddr, (void *)addr, size, 0,
"bus_alloc_resource(MEMORY)");
if (res->mapped_area < 0)
return -1;
res->tag = I386_BUS_SPACE_MEM;
res->handle = (bus_space_handle_t)virtualAddr;
return 0;
}
static int
bus_alloc_ioport_resource(device_t dev, struct resource *res, int regid)
{
res->tag = I386_BUS_SPACE_IO;
res->handle = pci_read_config(dev, regid, 4) & PCI_address_io_mask;
return 0;
}
struct resource *
bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start,
unsigned long end, unsigned long count, uint32 flags)
{
switch (type) {
case SYS_RES_IRQ:
{
uint8 res = pci_read_config(dev, PCI_interrupt_line, 1);
if (res == 0 || res == 0xff)
return NULL;
return (struct resource *)(int)res;
}
struct resource *res;
int result = -1;
case SYS_RES_MEMORY:
{
uint32 res = pci_read_config(dev, *rid, 4)
& PCI_address_memory_32_mask;
uint32 size = 128 * 1024; // TODO get size from BAR
void *virtualAddr;
if (map_mem(&virtualAddr, (void *)res, size, 0, "bus_alloc_resource(MEMORY)") < 0)
return NULL;
return (struct resource *)virtualAddr;
}
if (type != SYS_RES_IRQ && type != SYS_RES_MEMORY
&& type != SYS_RES_IOPORT)
return NULL;
case SYS_RES_IOPORT:
return (struct resource *)(pci_read_config(dev, *rid, 4)
& PCI_address_io_mask);
// maybe a local array of resources is enough
res = malloc(sizeof(struct resource));
if (res == NULL)
return NULL;
default:
return NULL;
if (type == SYS_RES_IRQ)
result = bus_alloc_irq_resource(dev, res);
else if (type == SYS_RES_MEMORY)
result = bus_alloc_mem_resource(dev, res, *rid);
else if (type == SYS_RES_IOPORT)
result = bus_alloc_ioport_resource(dev, res, *rid);
if (result < 0) {
free(res);
return NULL;
}
res->type = type;
return res;
}
int
bus_release_resource(device_t dev, int type, int rid, struct resource *res)
{
switch (type) {
case SYS_RES_IRQ:
case SYS_RES_IOPORT:
return 0;
if (res->type != type)
panic("bus_release_resource: mismatch");
case SYS_RES_MEMORY:
delete_area(area_for(res));
return 0;
if (type == SYS_RES_MEMORY)
delete_area(res->mapped_area);
default:
return B_ERROR;
}
free(res);
return 0;
}
bus_space_handle_t
rman_get_bushandle(struct resource *res)
{
return res->handle;
}
bus_space_tag_t
rman_get_bustag(struct resource *res)
{
return res->tag;
}

File diff suppressed because it is too large Load Diff

View File

@ -74,6 +74,28 @@ device_printf(device_t dev, const char *format, ...)
}
int
printf(const char *format, ...)
{
char buf[256];
va_list vl;
va_start(vl, format);
vsnprintf(buf, sizeof(buf), format, vl);
va_end(vl);
dprintf(buf);
return 0;
}
int resource_int_value(const char *name, int unit, const char *resname,
int *result)
{
/* no support for hints */
return -1;
}
void *
_kernel_malloc(size_t size, int flags)
{
@ -90,6 +112,33 @@ _kernel_free(void *ptr)
}
void *
_kernel_contigmalloc(const char *file, int line, size_t size, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
unsigned long boundary)
{
char name[256];
area_id area;
void *addr;
snprintf(name, sizeof(name), "contig:%s:%d", file, line);
area = create_area(name, &addr, B_ANY_KERNEL_ADDRESS, size,
B_FULL_LOCK | B_CONTIGUOUS, 0);
if (area < 0)
return NULL;
return addr;
}
void
_kernel_contigfree(void *addr, size_t size)
{
delete_area(area_for(addr));
}
status_t
init_compat_layer()
{

View File

@ -0,0 +1,12 @@
#ifndef _FBSD_COMPAT_MACHINE_ATOMIC_H_
#define _FBSD_COMPAT_MACHINE_ATOMIC_H_
#include <KernelExport.h>
#define atomic_add_int(ptr, value) \
atomic_add((int32 *)ptr, value)
#define atomic_subtract_int(ptr, value) \
atomic_add((int32 *)ptr, -value)
#endif

View File

@ -4,6 +4,7 @@
#include <arch/x86/arch_cpu.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
// TODO per platform, these are x86
typedef uint32_t bus_addr_t;
@ -146,6 +147,18 @@ void device_set_desc(device_t dev, const char *desc);
device_t device_add_child(device_t dev, const char *name, int unit);
int device_delete_child(device_t dev, device_t child);
static inline struct sysctl_ctx_list *
device_get_sysctl_ctx(device_t dev)
{
return NULL;
}
static inline void *
device_get_sysctl_tree(device_t dev)
{
return NULL;
}
#include <sys/bus_dma.h>
#endif

View File

@ -1,6 +1,6 @@
#ifndef _FBSD_COMPAT_SYS_CDEFS_H_
#define _FBSD_COMPAT_SYS_CDEFS_H_
#define __FBSDID(str) const char __fbsdid[] = str
#define __FBSDID(str) static const char __fbsdid[] = str
#endif

View File

@ -2,6 +2,7 @@
#define _FBSD_COMPAT_SYS_KERNEL_H_
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <KernelExport.h>
@ -17,6 +18,15 @@
panic msg; \
} while(0)
typedef void (*system_init_func_t)(void *);
struct __system_init {
system_init_func_t func;
};
/* TODO */
#define SYSINIT(uniquifier, subsystem, order, func, ident) \
struct __system_init __init_##uniquifier = { func }
#define __printflike(a, b) __attribute__ ((format (__printf__, a, b)))

View File

@ -3,6 +3,8 @@
#include <malloc.h>
#include <vm/vm.h>
#define M_NOWAIT 0x0001
#define M_WAITOK 0x0002
#define M_ZERO 0x0100
@ -11,10 +13,22 @@
void *_kernel_malloc(size_t size, int flags);
void _kernel_free(void *ptr);
void *_kernel_contigmalloc(const char *file, int line, size_t size, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
unsigned long boundary);
void _kernel_contigfree(void *addr, unsigned long size);
#define kernel_malloc(size, base, flags) \
_kernel_malloc(size, flags)
#define kernel_free( ptr, base) \
_kernel_free(ptr)
#define kernel_contigmalloc(size, base, flags, low, high, alignment, boundary) \
_kernel_contigmalloc(__FILE__, __LINE__, size, flags, low, high, \
alignment, boundary)
#define kernel_contigfree(addr, size, base) \
_kernel_contigfree(addr, size)
#endif

View File

@ -81,6 +81,11 @@ struct mbuf *m_defrag(struct mbuf *m, int);
#define mtod(m, type) (type)((m)->m_data)
/* Check if the supplied mbuf has a packet header, or else panic. */
#define M_ASSERTPKTHDR(m) \
KASSERT(m != NULL && m->m_flags & M_PKTHDR, \
("%s: no mbuf packet header!", __func__))
#endif
#endif

View File

@ -4,7 +4,21 @@
#include <posix/sys/param.h>
#define MAXBSIZE 0x10000
#define PAGE_SHIFT 12
#define PAGE_SIZE B_PAGE_SIZE
#define PAGE_MASK (PAGE_SIZE - 1)
#define trunc_page(x) ((x) & ~PAGE_MASK)
#define ptoa(x) ((unsigned long)((x) << PAGE_SHIFT))
#define atop(x) ((unsigned long)((x) >> PAGE_SHIFT))
/* MAJOR FIXME */
#define Maxmem (32768)
#ifndef MSIZE
#define MSIZE 256

View File

@ -7,35 +7,120 @@ struct sysctl_req {
void *newptr;
};
struct sysctl_ctx_list {
};
#define SYSCTL_HANDLER_ARGS void *oidp, void *arg1, void *arg2, struct sysctl_req *req
#define OID_AUTO (-1)
#define CTLTYPE 0xf
#define CTLTYPE_NONE 1
#define CTLTYPE_INT 2
#define CTLTYPE_STRING 3
#define CTLTYPE 0xf /* Mask for the type */
#define CTLTYPE_NODE 1 /* name is a node */
#define CTLTYPE_INT 2 /* name describes an integer */
#define CTLTYPE_STRING 3 /* name describes a string */
#define CTLTYPE_QUAD 4 /* name describes a 64-bit number */
#define CTLTYPE_OPAQUE 5 /* name describes a structure */
#define CTLTYPE_STRUCT CTLTYPE_OPAQUE /* name describes a structure */
#define CTLTYPE_UINT 6 /* name describes an unsigned integer */
#define CTLTYPE_LONG 7 /* name describes a long */
#define CTLTYPE_ULONG 8 /* name describes an unsigned long */
#define CTLFLAG_RD 0x80000000
#define CTLFLAG_WR 0x40000000
#define CTLFLAG_RW (CTLFLAG_RD | CTLFLAG_WR)
static void SYSCTL_ADD_PROC(void *a, void *b, int c, const char *d, int e,
void *f, int g, int (*h)(SYSCTL_HANDLER_ARGS), const char *i, const char *j)
{
}
#define SYSCTL_ADD_INT(...)
#define SYSCTL_CHILDREN(...) NULL
#define device_get_sysctl_ctx(dev) NULL
#define CTLFLAG_RD 0x80000000 /* Allow reads of variable */
#define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */
#define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR)
#define CTLFLAG_NOLOCK 0x20000000 /* XXX Don't Lock */
#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */
#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */
#define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */
#define CTLFLAG_DYN 0x02000000 /* Dynamic oid - can be freed */
#define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */
#define CTLMASK_SECURE 0x00F00000 /* Secure level */
#define CTLFLAG_TUN 0x00080000 /* Tunable variable */
#define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN)
static inline int
sysctl_handle_int(SYSCTL_HANDLER_ARGS)
sysctl_ctx_init(struct sysctl_ctx_list *clist)
{
return 0;
return -1;
}
static inline int
sysctl_ctx_free(struct sysctl_ctx_list *clist)
{
return -1;
}
static inline void *
sysctl_add_oid(struct sysctl_ctx_list *clist,
void *parent, int nbr, const char *name,
int kind, void *arg1, int arg2,
int (*handler) (SYSCTL_HANDLER_ARGS),
const char *fmt, const char *descr)
{
return NULL;
}
static inline int sysctl_handle_long(SYSCTL_HANDLER_ARGS) { return -1; }
static inline int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS) { return -1; }
static inline int sysctl_handle_int(SYSCTL_HANDLER_ARGS) { return -1; }
static inline int sysctl_handle_string(SYSCTL_HANDLER_ARGS) { return -1; }
#define __DESCR(x) ""
#define SYSCTL_ADD_OID(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, descr) \
sysctl_add_oid(ctx, parent, nbr, name, kind, a1, a2, handler, fmt, __DESCR(descr))
#define SYSCTL_ADD_NODE(ctx, parent, nbr, name, access, handler, descr) \
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_NODE|(access), \
0, 0, handler, "N", __DESCR(descr))
#define SYSCTL_ADD_STRING(ctx, parent, nbr, name, access, arg, len, descr) \
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_STRING|(access), \
arg, len, sysctl_handle_string, "A", __DESCR(descr))
#define SYSCTL_ADD_INT(ctx, parent, nbr, name, access, ptr, val, descr) \
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_INT|(access), \
ptr, val, sysctl_handle_int, "I", __DESCR(descr))
#define SYSCTL_ADD_UINT(ctx, parent, nbr, name, access, ptr, val, descr) \
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_UINT|(access), \
ptr, val, sysctl_handle_int, "IU", __DESCR(descr))
#define SYSCTL_ADD_LONG(ctx, parent, nbr, name, access, ptr, descr) \
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_LONG|(access), \
ptr, 0, sysctl_handle_long, "L", __DESCR(descr))
#define SYSCTL_ADD_ULONG(ctx, parent, nbr, name, access, ptr, descr) \
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_ULONG|(access), \
ptr, 0, sysctl_handle_long, "LU", __DESCR(descr))
#define SYSCTL_ADD_OPAQUE(ctx, parent, nbr, name, access, ptr, len, fmt, descr)\
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \
ptr, len, sysctl_handle_opaque, fmt, __DESCR(descr))
#define SYSCTL_ADD_STRUCT(ctx, parent, nbr, name, access, ptr, type, descr) \
sysctl_add_oid(ctx, parent, nbr, name, CTLTYPE_OPAQUE|(access), \
ptr, sizeof(struct type), sysctl_handle_opaque, "S," #type, __DESCR(descr))
#define SYSCTL_ADD_PROC(ctx, parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
sysctl_add_oid(ctx, parent, nbr, name, (access), \
ptr, arg, handler, fmt, __DESCR(descr))
static inline void *
SYSCTL_CHILDREN(void *ptr)
{
return NULL;
}
#define SYSCTL_STATIC_CHILDREN(...) NULL
#define SYSCTL_NODE(...)
#define SYSCTL_INT(...)
#endif
#endif

View File

@ -0,0 +1,35 @@
#ifndef _FBSD_COMPAT_VM_VM_H_
#define _FBSD_COMPAT_VM_VM_H_
#include <stdint.h>
#include <KernelExport.h>
// for x86
typedef uint32_t vm_offset_t;
typedef uint32_t vm_paddr_t;
typedef void * pmap_t;
#define vmspace_pmap(...) NULL
#define pmap_extract(...) NULL
#define pmap_kextract(vaddr) vtophys(vaddr)
/* Marcus' vtophys */
static inline unsigned long
vtophys(vm_offset_t vaddr)
{
physical_entry pe;
status_t status;
status = get_memory_map((void *)vaddr, 1, &pe, 1);
if (status < 0)
panic("fbsd compat: get_memory_map failed for %p, error %08lx\n",
(void *)vaddr, status);
return (unsigned long)pe.address;
}
#endif