[BACK]Return to driver.h CVS log [TXT][DIR] Up to [local] / prex / dev / include

File: [local] / prex / dev / include / driver.h (download)

Revision 1.1, Tue Aug 19 12:46:47 2008 UTC (15 years, 8 months ago) by nbrk
Branch point for: MAIN

Initial revision

/*
 * Copyright (c) 2005-2007, Kohsuke Ohtani
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
 */

/*
 * driver.h - Kernel Interface for device driver
 */

#ifndef _DRIVER_H
#define _DRIVER_H

#include <conf/config.h>
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/list.h>
#include <prex/bootinfo.h>
#include <queue.h>
#include <drvlib.h>

/*
 * Kernel types
 */
typedef unsigned long	device_t;
typedef unsigned long	task_t;
typedef unsigned long	irq_t;

#define DEVICE_NULL	((device_t)0)
#define TASK_NULL	((task_t)0)
#define IRQ_NULL	((irq_t)0)

/*
 * Driver structure
 *
 * "order" is initialize order which must be between 0 and 15.
 * The driver with order 0 is called first.
 */
struct driver {
	const char	*name;		/* Name of device driver */
	const int	order;		/* Initialize order */
	int		(*init)(void);	/* Initialize routine */
};

/*
 * Device I/O table
 */
struct devio {
	int (*open)	(device_t dev, int mode);
	int (*close)	(device_t dev);
	int (*read)	(device_t dev, char *buf, size_t *nbyte, int blkno);
	int (*write)	(device_t dev, char *buf, size_t *nbyte, int blkno);
	int (*ioctl)	(device_t dev, u_long arg, void *);
	int (*event)	(int event);
};

/*
 * Flags for device_create()
 */
#define DF_CHR		0x00000001	/* Character device */
#define DF_BLK		0x00000002	/* Block device */
#define DF_RDONLY	0x00000004	/* Read only device */
#define DF_REM		0x00000008	/* Removable device */

/*
 * Device open mode
 */
#define DO_RDONLY	0x0
#define DO_WRONLY	0x1
#define DO_RDWR		0x2
#define DO_RWMASK	0x3

/*
 * Return value of ISR
 */
#define INT_DONE	0
#define INT_ERROR	1
#define INT_CONTINUE	2

/*
 * Interrupt priority levels
 */
#define IPL_NONE	0	/* Nothing */
#define IPL_COMM	1	/* Serial, Parallel */
#define IPL_BLOCK	2	/* FDD, IDE */
#define IPL_NET		3	/* Network */
#define IPL_DISPLAY	4	/* Screen */
#define IPL_INPUT	5	/* Keyboard, Mouse */
#define IPL_AUDIO	6	/* Audio */
#define IPL_BUS		7	/* USB, PCCARD */
#define IPL_RTC		8	/* RTC Alarm */
#define IPL_PROFILE	9	/* Profiling timer */
#define IPL_CLOCK	10	/* System Clock Timer */
#define IPL_HIGH	11	/* Everything */

#define NIPL		12

/*
 * Event for sleep/wakeup
 */
struct event {
	struct queue	sleepq;		/* queue for waiting thread */
	const char	*name;		/* pointer to event name string */
};

#define event_init(event, evt_name) \
    do { list_init(&(event)->sleepq); (event)->name = evt_name; } while (0)

/*
 * Sleep result
 */
#define SLP_SUCCESS	0
#define SLP_BREAK	1
#define SLP_TIMEOUT	2
#define SLP_INVAL	3
#define SLP_INTR	4

/*
 * DPC (Deferred Procedure Call) object
 */
struct dpc {
	struct queue	link;		/* Linkage on DPC queue */
	int		state;
	void		(*func)(void *); /* Call back routine */
	void		*arg;		/* Argument to pass */
};

/*
 * Macro to convert milliseconds and tick.
 */
#define msec_to_tick(ms) (((ms) >= 0x20000) ? \
	    ((ms) / 1000UL) * HZ : \
	    ((ms) * HZ) / 1000UL)

#define tick_to_msec(tick) (((tick) * 1000) / HZ)

/*
 * Timer structure
 */
struct timer {
	struct list	link;		/* Linkage on timer chain */
	int		active;		/* True if active */
	u_long		expire;		/* Expire time (ticks) */
	u_long		interval;	/* Time interval */
	void		(*func)(void *); /* Function to call */
	void		*arg;		/* Function argument */
	struct event	event;		/* Event for this timer */
};

#define timer_init(tmr)     (tmr)->expire = 0;

/*
 * Items for debug_dump()
 */
#define DUMP_THREAD	1
#define DUMP_TASK	2
#define DUMP_VM		3

__BEGIN_DECLS
device_t device_create(struct devio *io, const char *name, int flags);
int	 device_destroy(device_t dev);
int	 device_broadcast(int event, int force);

int	 umem_copyin(const void *uaddr, void *kaddr, size_t len);
int	 umem_copyout(const void *kaddr, void *uaddr, size_t len);
int	 umem_strnlen(const char *uaddr, size_t maxlen, size_t *len);

void	*kmem_alloc(size_t size);
void	 kmem_free(void *ptr);
void	*kmem_map(void *addr, size_t size);

void	*page_alloc(size_t size);
void	 page_free(void *paddr, size_t size);
int	 page_reserve(void *paddr, size_t size);

irq_t	 irq_attach(int irqno, int level, int shared, int (*isr)(int), void (*ist)(int));
void	 irq_detach(irq_t irq);
void	 irq_lock(void);
void	 irq_unlock(void);

void	 timer_callout(struct timer *tmr, u_long msec, void (*func)(void *), void *arg);
void	 timer_stop(struct timer *tmr);
u_long	 timer_delay(u_long msec);
u_long	 timer_count(void);
int	 timer_hook(void (*func)(int));

void	 sched_lock(void);
void	 sched_unlock(void);
int	 sched_tsleep(struct event *evt, u_long timeout);
void	 sched_wakeup(struct event *evt);
void	 sched_dpc(struct dpc *dpc, void (*func)(void *), void *arg);
#define	 sched_sleep(event)  sched_tsleep((event), 0)

int	 exception_post(task_t task, int exc);
int	 task_capable(int cap);

void	*phys_to_virt(void *p_addr);
void	*virt_to_phys(void *v_addr);

void	 machine_reset(void);
void	 machine_idle(void);
void	 machine_bootinfo(struct boot_info **);

void	 debug_attach(void (*func)(char *));
int	 debug_dump(int index);

void	 printf(const char *fmt, ...);
void	 panic(const char *msg);
#ifdef DEBUG
void	 assert(const char *file, int line, const char *exp);
#define ASSERT(exp) do { if (!(exp)) \
			     assert(__FILE__, __LINE__, #exp); } while (0)
#else
#define ASSERT(exp) do {} while (0)
#endif

void	driver_main(void);
__END_DECLS

#endif /* !_DRIVER_H */