1) common headers

2) usb code

git-svn-id: svn://kolibrios.org@954 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-12-13 03:32:16 +00:00
parent 0d893d8b84
commit e8b3efcc2d
25 changed files with 3377 additions and 48 deletions

View File

@ -500,8 +500,6 @@ void agp_device_command(u32_t bridge_agpstat, int agp_v3)
}
void agp_generic_enable(u32_t requested_mode)
{
u32_t bridge_agpstat, temp;

View File

@ -115,4 +115,28 @@ typedef struct
// void (*agp_destroy_page)(void *);
}agp_t;
/*
* min()/max() macros that also do
* strict type-checking.. See the
* "unnecessary" pointer comparison.
*/
#define min(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; })
#define max(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x > _y ? _x : _y; })
#define min_t(type,x,y) \
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
#define max_t(type,x,y) \
({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })

View File

@ -4,9 +4,12 @@ FASM = e:/fasm/fasm.exe
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
LDRHD = -shared -T ld.x -s --file-alignment 32
HFILES:= agp.h \
syscall.h \
pci.h \
INCLUDES = -I ../include
HFILES:= ../include/types.h \
../include/syscall.h \
agp.h \
pci.h \
SRC_DEP:= pci.inc \
detect.inc \
@ -24,7 +27,7 @@ $(AGP): agp.obj $(SRC_DEP) $(HFILES) Makefile
kpack.exe agp.dll agp.drv
agp.obj : agp.c $(SRC_DEP) $(HFILES) Makefile
$(CC) $(CFLAGS) -o agp.obj agp.c
$(CC) $(INCLUDES) $(CFLAGS) -o agp.obj agp.c

View File

@ -129,7 +129,10 @@ typedef struct
int w;
int h;
color_t key;
union {
color_t key;
color_t alpha;
};
}io_blit_t;

View File

@ -146,7 +146,7 @@ int __stdcall srv_2d(ioctl_t *io)
break;
case PX_BLIT_ALPHA:
if(io->inp_size==8)
if(io->inp_size==9)
return RadeonComposite((io_blit_t*)inp);
break;

View File

@ -91,7 +91,7 @@ typedef enum
(info->ChipFamily == CHIP_FAMILY_RS600) || \
(info->ChipFamily == CHIP_FAMILY_RS740) || \
(info->ChipFamily == CHIP_FAMILY_RS400) || \
(info->ChipFamily == CHIP_FAMILY_RS480))
(info->ChipFamily == CHIP_FAMILY_RS480))

View File

@ -34,6 +34,63 @@ static struct blendinfo RadeonBlendOp[] = {
{0, 0, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ONE},
};
static Bool R200PrepareComposite(local_pixmap_t *dstpix, int dstX, int dstY,
local_pixmap_t *srcpix, int srcX, int srcY,
int w, int h, int alpha)
{
u32_t tex_size = 0, txformat, blend_cntl;
int dst_pitch;
if ((w > 2048) || (h > 2048))
return FALSE;
txformat = RADEON_TXFORMAT_ARGB8888 |
RADEON_TXFORMAT_ALPHA_IN_MAP |
RADEON_TXFORMAT_NON_POWER2;
blend_cntl = RADEON_SRC_BLEND_GL_SRC_ALPHA |
RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
tex_size = ((h - 1) << 16) | (w - 1);
{
u32_t *ring;
u32_t ifl = safe_cli();
BEGIN_ACCEL(168);
OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat);
OUT_ACCEL_REG(R200_PP_TXFORMAT_X_0, 0);
OUT_ACCEL_REG(R200_PP_TXSIZE_0, tex_size);
OUT_ACCEL_REG(R200_PP_TXPITCH_0, srcpix->pitch - 32);
OUT_ACCEL_REG(R200_PP_TXOFFSET_0, (u32_t)srcpix->local);
OUT_ACCEL_REG(R200_PP_TXFILTER_0, R200_MAG_FILTER_NEAREST |
R200_MIN_FILTER_NEAREST |
R200_CLAMP_S_WRAP |
R200_CLAMP_T_WRAP);
OUT_ACCEL_REG(RADEON_RB3D_CNTL, RADEON_COLOR_FORMAT_ARGB8888 |
RADEON_ALPHA_BLEND_ENABLE);
OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE |
RADEON_TEX_BLEND_0_ENABLE);
OUT_ACCEL_REG(R200_PP_TFACTOR_0, alpha << 24);
OUT_ACCEL_REG(R200_PP_TXCBLEND_0, R200_TXC_ARG_A_TFACTOR_COLOR |
R200_TXC_ARG_B_R0_ALPHA);
OUT_ACCEL_REG(R200_PP_TXCBLEND2_0,R200_TXC_OUTPUT_REG_R0);
OUT_ACCEL_REG(R200_PP_TXABLEND_0, R200_TXA_ARG_A_TFACTOR_ALPHA |
R200_TXA_ARG_B_R0_ALPHA);
OUT_ACCEL_REG(R200_PP_TXABLEND2_0, R200_TXA_OUTPUT_REG_R0);
OUT_ACCEL_REG(R200_SE_VTX_FMT_0, 0);
OUT_ACCEL_REG(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT));
OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl);
OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, dstpix->pitch >> 2);
OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, (u32_t)dstpix->local);
COMMIT_RING();
safe_sti(ifl);
};
return TRUE;
}
static Bool R300TextureSetup(RHDPtr info,local_pixmap_t *srcpix, int w, int h, int unit)
{
@ -67,7 +124,7 @@ static Bool R300TextureSetup(RHDPtr info,local_pixmap_t *srcpix, int w, int h, i
//txformat1 = R300TexFormats[i].card_fmt;
txformat1 = R300_TX_FORMAT_A8R8G8B8;// R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
txformat1 = R300_TX_FORMAT_A8R8G8B8;
txformat0 = ((((w - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) |
(((h - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT));
@ -253,12 +310,14 @@ Bool R300PrepareComposite(local_pixmap_t *dstpix, int dstX, int dstY,
* - Xv
* Here we select the offset of the vertex program we want to use
*/
if (info->has_tcl) {
OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_0,
((3 << R300_PVS_FIRST_INST_SHIFT) |
(4 << R300_PVS_XYZW_VALID_INST_SHIFT) |
(4 << R300_PVS_LAST_INST_SHIFT)));
((3 << R300_PVS_FIRST_INST_SHIFT) |
(4 << R300_PVS_XYZW_VALID_INST_SHIFT) |
(4 << R300_PVS_LAST_INST_SHIFT)));
OUT_ACCEL_REG(R300_VAP_PVS_CODE_CNTL_1,
(4 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
(4 << R300_PVS_LAST_VTX_SRC_INST_SHIFT));
}
/* Position and one or two sets of 2 texture coordinates */
OUT_ACCEL_REG(R300_VAP_OUT_VTX_FMT_0, R300_VTX_POS_PRESENT); //VTX_COLOR_0_PRESENT
@ -274,6 +333,111 @@ Bool R300PrepareComposite(local_pixmap_t *dstpix, int dstX, int dstY,
/* setup pixel shader */
if (IS_R300_3D)
{
u32_t output_fmt;
int src_color, src_alpha;
int mask_color, mask_alpha;
src_color = R300_ALU_RGB_SRC0_RGB;
src_alpha = R300_ALU_ALPHA_SRC0_A;
mask_color = R300_ALU_RGB_1_0;
mask_alpha = R300_ALU_ALPHA_1_0;
/* shader output swizzling */
output_fmt = (R300_OUT_FMT_C4_8 |
R300_OUT_FMT_C0_SEL_BLUE |
R300_OUT_FMT_C1_SEL_GREEN |
R300_OUT_FMT_C2_SEL_RED |
R300_OUT_FMT_C3_SEL_ALPHA);
/* setup the rasterizer, load FS */
BEGIN_ACCEL(10);
/* 2 components: 2 for tex0 */
OUT_ACCEL_REG(R300_RS_COUNT,
((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
R300_RS_COUNT_HIRES_EN));
OUT_ACCEL_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6));
OUT_ACCEL_REG(R300_US_CODE_OFFSET, (R300_ALU_CODE_OFFSET(0) |
R300_ALU_CODE_SIZE(0) |
R300_TEX_CODE_OFFSET(0) |
R300_TEX_CODE_SIZE(0)));
OUT_ACCEL_REG(R300_US_CODE_ADDR_3,
(R300_ALU_START(0) |
R300_ALU_SIZE(0) |
R300_TEX_START(0) |
R300_TEX_SIZE(0) |
R300_RGBA_OUT));
OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* highest temp used */
/* shader output swizzling */
OUT_ACCEL_REG(R300_US_OUT_FMT_0, output_fmt);
/* tex inst for src texture is pre-loaded in RADEONInit3DEngine() */
/* tex inst for mask texture is pre-loaded in RADEONInit3DEngine() */
/* RGB inst
* temp addresses for texture inputs
* ALU_RGB_ADDR0 is src tex (temp 0)
* ALU_RGB_ADDR1 is mask tex (temp 1)
* R300_ALU_RGB_OMASK - output components to write
* R300_ALU_RGB_TARGET_A - render target
*/
OUT_ACCEL_REG(R300_US_ALU_RGB_ADDR(0),
(R300_ALU_RGB_ADDR0(0) |
R300_ALU_RGB_ADDR1(1) |
R300_ALU_RGB_ADDR2(0) |
R300_ALU_RGB_ADDRD(0) |
R300_ALU_RGB_OMASK((R300_ALU_RGB_MASK_R |
R300_ALU_RGB_MASK_G |
R300_ALU_RGB_MASK_B)) |
R300_ALU_RGB_TARGET_A));
/* RGB inst
* ALU operation
*/
OUT_ACCEL_REG(R300_US_ALU_RGB_INST(0),
(R300_ALU_RGB_SEL_A(src_color) |
R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) |
R300_ALU_RGB_SEL_B(mask_color) |
R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) |
R300_ALU_RGB_SEL_C(R300_ALU_RGB_0_0) |
R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) |
R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) |
R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE) |
R300_ALU_RGB_CLAMP));
/* Alpha inst
* temp addresses for texture inputs
* ALU_ALPHA_ADDR0 is src tex (0)
* ALU_ALPHA_ADDR1 is mask tex (1)
* R300_ALU_ALPHA_OMASK - output components to write
* R300_ALU_ALPHA_TARGET_A - render target
*/
OUT_ACCEL_REG(R300_US_ALU_ALPHA_ADDR(0),
(R300_ALU_ALPHA_ADDR0(0) |
R300_ALU_ALPHA_ADDR1(1) |
R300_ALU_ALPHA_ADDR2(0) |
R300_ALU_ALPHA_ADDRD(0) |
R300_ALU_ALPHA_OMASK(R300_ALU_ALPHA_MASK_A) |
R300_ALU_ALPHA_TARGET_A |
R300_ALU_ALPHA_OMASK_W(R300_ALU_ALPHA_MASK_NONE)));
/* Alpha inst
* ALU operation
*/
OUT_ACCEL_REG(R300_US_ALU_ALPHA_INST(0),
(R300_ALU_ALPHA_SEL_A(src_alpha) |
R300_ALU_ALPHA_MOD_A(R300_ALU_ALPHA_MOD_NOP) |
R300_ALU_ALPHA_SEL_B(mask_alpha) |
R300_ALU_ALPHA_MOD_B(R300_ALU_ALPHA_MOD_NOP) |
R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0) |
R300_ALU_ALPHA_MOD_C(R300_ALU_ALPHA_MOD_NOP) |
R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) |
R300_ALU_ALPHA_OMOD(R300_ALU_ALPHA_OMOD_NONE) |
R300_ALU_ALPHA_CLAMP));
FINISH_ACCEL();
}
else
{
@ -287,8 +451,8 @@ Bool R300PrepareComposite(local_pixmap_t *dstpix, int dstX, int dstY,
// R500_ALU_RGB_B_SWIZ_A_0);
// else
src_color = (R500_ALU_RGB_R_SWIZ_A_R |
R500_ALU_RGB_G_SWIZ_A_G |
R500_ALU_RGB_B_SWIZ_A_B);
R500_ALU_RGB_G_SWIZ_A_G |
R500_ALU_RGB_B_SWIZ_A_B);
// if (PICT_FORMAT_A(PICT_a8r8g8b8) == 0)
// src_alpha = R500_ALPHA_SWIZ_A_1;
@ -445,16 +609,16 @@ static __inline__ u32_t F_TO_DW(float val)
#define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
#define VTX_OUT(_dstX, _dstY, _srcX, _srcY) \
do { \
OUT_RING_F(_dstX); \
OUT_RING_F(_dstY); \
OUT_RING_F(_srcX); \
OUT_RING_F(_srcY); \
do { \
OUT_RING_F(_dstX); \
OUT_RING_F(_dstY); \
OUT_RING_F(_srcX); \
OUT_RING_F(_srcY); \
} while (0)
static int RadeonCompositeTile(int srcX, int srcY,
static int R300CompositeTile(int srcX, int srcY,
int dstX, int dstY,
int w, int h)
{
@ -532,7 +696,7 @@ static int RadeonCompositeTile(int srcX, int srcY,
/* flushing is pipelined, free/finish is not */
OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D);
OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
// OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
COMMIT_RING();
@ -540,6 +704,59 @@ static int RadeonCompositeTile(int srcX, int srcY,
// LEAVE_DRAW(0);
}
static int R200CompositeTile(int srcX, int srcY,
int dstX, int dstY,
int w, int h)
{
xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight;
xPointFixed maskTopLeft, maskTopRight, maskBottomLeft, maskBottomRight;
srcTopLeft.x = IntToxFixed(srcX);
srcTopLeft.y = IntToxFixed(srcY);
srcTopRight.x = IntToxFixed(srcX + w);
srcTopRight.y = IntToxFixed(srcY);
srcBottomLeft.x = IntToxFixed(srcX);
srcBottomLeft.y = IntToxFixed(srcY + h);
srcBottomRight.x = IntToxFixed(srcX + w);
srcBottomRight.y = IntToxFixed(srcY + h);
{
u32_t *ring;
u32_t ifl = safe_cli();
BEGIN_RING(4 + 4 * VTX_COUNT);
OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, 4 * VTX_COUNT));
OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN |
RADEON_CP_VC_CNTL_PRIM_WALK_RING |
(4 << RADEON_CP_VC_CNTL_NUM_SHIFT));
VTX_OUT((float)dstX, (float)dstY,
xFixedToFloat(srcTopLeft.x) / w, // info->texW[0],
xFixedToFloat(srcTopLeft.y) / h); // info->texH[0]);
VTX_OUT((float)dstX, (float)(dstY + h),
xFixedToFloat(srcBottomLeft.x) / w, // info->texW[0],
xFixedToFloat(srcBottomLeft.y) / h); // info->texH[0]);
VTX_OUT((float)(dstX + w), (float)(dstY + h),
xFixedToFloat(srcBottomRight.x) / w, // info->texW[0],
xFixedToFloat(srcBottomRight.y) / h); // info->texH[0]);
VTX_OUT((float)(dstX + w), (float)dstY,
xFixedToFloat(srcTopRight.x) / w, // info->texW[0],
xFixedToFloat(srcTopRight.y) / h); // info->texH[0]);
OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
COMMIT_RING();
safe_sti(ifl);
};
};
#undef VTX_OUT
#undef VTX_OUT_MASK
@ -576,24 +793,45 @@ int RadeonComposite( io_blit_t *blit)
);
OUT_RING(srcpixmap->pitch_offset);
OUT_RING(blit->key);
OUT_RING(blit->alpha<<24);
OUT_RING( 0 );
OUT_RING((srcpixmap->width<<16)|srcpixmap->height);
COMMIT_RING();
RHDPtr info = &rhd;
if( IS_R300_3D || IS_R500_3D )
{
R300PrepareComposite(dstpixmap, blit->dst_x, blit->dst_y,
srcpixmap, blit->src_x, blit->src_y,
blit->w, blit->h, 3);
// if (!need_src_tile_x && !need_src_tile_y) {
R300CompositeTile( blit->src_x, blit->src_y,
blit->dst_x, blit->dst_y,
blit->w, blit->h);
}
else if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
(info->ChipFamily == CHIP_FAMILY_RV280) ||
(info->ChipFamily == CHIP_FAMILY_RS300) ||
(info->ChipFamily == CHIP_FAMILY_R200))
{
R200PrepareComposite(dstpixmap, blit->dst_x, blit->dst_y,
srcpixmap, blit->src_x, blit->src_y,
blit->w, blit->h, blit->alpha);
R200CompositeTile( blit->src_x, blit->src_y,
blit->dst_x, blit->dst_y,
blit->w, blit->h);
};
safe_sti(ifl);
};
R300PrepareComposite(dstpixmap, blit->dst_x, blit->dst_y,
srcpixmap, blit->src_x, blit->src_y,
blit->w, blit->h, 3);
// if (!need_src_tile_x && !need_src_tile_y) {
RadeonCompositeTile( blit->src_x, blit->src_y,
blit->dst_x, blit->dst_y,
blit->w, blit->h);
return 0;
return 0;
// }
/* Tiling logic borrowed from exaFillRegionTiled */

View File

@ -11,8 +11,6 @@ int Init3DEngine(RHDPtr info)
ifl = safe_cli();
if (IS_R300_3D || IS_R500_3D) {
BEGIN_ACCEL(3);
@ -617,11 +615,10 @@ int Init3DEngine(RHDPtr info)
OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, 0);
else
OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS);
OUT_ACCEL_REG(RADEON_SE_COORD_FMT,
RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
RADEON_VTX_ST0_NONPARAMETRIC |
RADEON_VTX_ST1_NONPARAMETRIC |
RADEON_TEX1_W_ROUTING_USE_W0);
OUT_ACCEL_REG(RADEON_SE_COORD_FMT, RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
RADEON_VTX_ST0_NONPARAMETRIC |
RADEON_VTX_ST1_NONPARAMETRIC |
RADEON_TEX1_W_ROUTING_USE_W0);
FINISH_ACCEL();
BEGIN_ACCEL(5);

View File

@ -4,11 +4,14 @@ FASM = e:/fasm/fasm.exe
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
LDRHD = -shared -T ld.x -s --file-alignment 32
HFILES:= ati2d.h \
syscall.h \
pci.h \
accel_2d.h \
r5xx_regs.h \
INCLUDES = -I ../include
HFILES:= ../include/types.h \
../include/syscall.h \
ati2d.h \
pci.h \
accel_2d.h \
r5xx_regs.h \
radeon_microcode.h
SRC_DEP:= init.c \
@ -40,7 +43,7 @@ $(ATI2D): $(ATI_OBJ) $(SRC_DEP) $(HFILES) Makefile
kpack.exe ati2d.dll ati2d.drv
ati2d.obj : ati2d.c $(SRC_DEP) $(HFILES) Makefile
$(CC) $(CFLAGS) -o ati2d.obj ati2d.c
$(CC) $(INCLUDES) $(CFLAGS) -o ati2d.obj ati2d.c
curhelp.obj : curhelp.asm
$(FASM) curhelp.asm

View File

@ -201,9 +201,6 @@ typedef struct
u32_t sign :1;
}src_t;
int parse_vs();
int parse_mov();
int parse_dcl();
int parse_vs(const u32_t *stream);

View File

@ -0,0 +1,60 @@
typedef struct link
{
struct link *prev;
struct link *next;
}link_t;
#define LIST_INITIALIZE(name) \
link_t name = { .prev = &name, .next = &name }
#define list_get_instance(link, type, member) \
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member))))
static inline void link_initialize(link_t *link)
{
link->prev = NULL;
link->next = NULL;
}
static inline void list_initialize(link_t *head)
{
head->prev = head;
head->next = head;
}
static inline void list_append(link_t *link, link_t *head)
{
link->prev = head->prev;
link->next = head;
head->prev->next = link;
head->prev = link;
}
static inline void list_remove(link_t *link)
{
link->next->prev = link->prev;
link->prev->next = link->next;
link_initialize(link);
}
static inline Bool list_empty(link_t *head)
{
return head->next == head ? TRUE : FALSE;
}
static inline void list_prepend(link_t *link, link_t *head)
{
link->next = head->next;
link->prev = head;
head->next->prev = link;
head->next = link;
}
static inline list_insert(link_t *new, link_t *old)
{
new->prev = old->prev;
new->next = old;
new->prev->next = new;
old->prev = new;
}

View File

@ -0,0 +1,299 @@
#define OS_BASE 0x80000000
typedef struct
{
u32_t handle;
u32_t io_code;
void *input;
int inp_size;
void *output;
int out_size;
}ioctl_t;
typedef int (__stdcall *srv_proc_t)(ioctl_t *);
#define ERR_OK 0
#define ERR_PARAM -1
u32_t __stdcall drvEntry(int)__asm__("_drvEntry");
///////////////////////////////////////////////////////////////////////////////
#define STDCALL __attribute__ ((stdcall)) __attribute__ ((dllimport))
#define IMPORT __attribute__ ((dllimport))
///////////////////////////////////////////////////////////////////////////////
#define SysMsgBoardStr __SysMsgBoardStr
#define PciApi __PciApi
//#define RegService __RegService
#define CreateObject __CreateObject
#define DestroyObject __DestroyObject
///////////////////////////////////////////////////////////////////////////////
#define PG_SW 0x003
#define PG_NOCACHE 0x018
void* STDCALL AllocKernelSpace(size_t size)__asm__("AllocKernelSpace");
void* STDCALL KernelAlloc(size_t size)__asm__("KernelAlloc");
void* STDCALL KernelFree(void *mem)__asm__("KernelFree");
void* STDCALL UserAlloc(size_t size)__asm__("UserAlloc");
int STDCALL UserFree(void *mem)__asm__("UserFree");
addr_t STDCALL AllocPages(count_t count)__asm__("AllocPages");
void* STDCALL CreateRingBuffer(size_t size, u32_t map)__asm__("CreateRingBuffer");
u32_t STDCALL RegService(char *name, srv_proc_t proc)__asm__("RegService");
//void *CreateObject(u32 pid, size_t size);
//void *DestroyObject(void *obj);
addr_t STDCALL MapIoMem(void* base,size_t size,u32_t flags)__asm__("MapIoMem");
///////////////////////////////////////////////////////////////////////////////
void STDCALL SetMouseData(int btn, int x, int y,
int z, int h)__asm__("SetMouseData");
static u32_t PciApi(int cmd);
u8_t STDCALL PciRead8 (u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead8");
u16_t STDCALL PciRead16(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead16");
u32_t STDCALL PciRead32(u32_t bus, u32_t devfn, u32_t reg)__asm__("PciRead32");
u32_t STDCALL PciWrite8 (u32_t bus, u32_t devfn, u32_t reg,u8_t val) __asm__("PciWrite8");
u32_t STDCALL PciWrite16(u32_t bus, u32_t devfn, u32_t reg,u16_t val)__asm__("PciWrite16");
u32_t STDCALL PciWrite32(u32_t bus, u32_t devfn, u32_t reg,u32_t val)__asm__("PciWrite32");
#define pciReadByte(tag, reg) \
PciRead8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
#define pciReadWord(tag, reg) \
PciRead16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
#define pciReadLong(tag, reg) \
PciRead32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg))
#define pciWriteByte(tag, reg, val) \
PciWrite8(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
#define pciWriteWord(tag, reg, val) \
PciWrite16(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
#define pciWriteLong(tag, reg, val) \
PciWrite32(PCI_BUS_FROM_TAG(tag),PCI_DFN_FROM_TAG(tag),(reg),(val))
///////////////////////////////////////////////////////////////////////////////
int dbg_open(char *path);
int dbgprintf(const char* format, ...);
///////////////////////////////////////////////////////////////////////////////
extern inline int GetScreenSize()
{
int retval;
asm("int $0x40"
:"=a"(retval)
:"a"(61), "b"(1));
return retval;
}
extern inline int GetScreenBpp()
{
int retval;
asm("int $0x40"
:"=a"(retval)
:"a"(61), "b"(2));
return retval;
}
extern inline int GetScreenPitch()
{
int retval;
asm("int $0x40"
:"=a"(retval)
:"a"(61), "b"(3));
return retval;
}
extern inline u32_t GetPgAddr(void *mem)
{
u32_t retval;
__asm__ __volatile__ (
"call *__imp__GetPgAddr \n\t"
:"=eax" (retval)
:"a" (mem) );
return retval;
};
extern inline void CommitPages(void *mem, u32_t page, u32_t size)
{
size = (size+4095) & ~4095;
__asm__ __volatile__ (
"call *__imp__CommitPages"
::"a" (page), "b"(mem),"c"(size>>12)
:"edx" );
__asm__ __volatile__ ("":::"eax","ebx","ecx");
};
extern inline void UnmapPages(void *mem, size_t size)
{
size = (size+4095) & ~4095;
__asm__ __volatile__ (
"call *__imp__UnmapPages"
::"a" (mem), "c"(size>>12)
:"edx");
__asm__ __volatile__ ("":::"eax","ecx");
};
extern inline void usleep(u32_t delay)
{
if( !delay )
delay++;
delay*=1000;
while(delay--)
__asm__ __volatile__ (
"xorl %%eax, %%eax \n\t"
"cpuid \n\t"
:::"eax","ebx","ecx","edx");
};
extern inline u32_t __PciApi(int cmd)
{
u32_t retval;
__asm__ __volatile__ (
"call *__imp__PciApi"
:"=a" (retval)
:"a" (cmd)
:"memory");
return retval;
};
extern inline void* __CreateObject(u32_t pid, size_t size)
{
void *retval;
__asm__ __volatile__ (
"call *__imp__CreateObject \n\t"
:"=a" (retval)
:"a" (size),"b"(pid)
:"esi","edi", "memory");
return retval;
}
extern inline void *__DestroyObject(void *obj)
{
__asm__ __volatile__ (
"call *__imp__DestroyObject"
:
:"a" (obj)
:"ebx","edx","esi","edi", "memory");
}
/*
u32 __RegService(char *name, srv_proc_t proc)
{
u32 retval;
asm __volatile__
(
"pushl %%eax \n\t"
"pushl %%ebx \n\t"
"call *__imp__RegService \n\t"
:"=eax" (retval)
:"a" (proc), "b" (name)
:"memory"
);
return retval;
};
*/
extern inline u32_t safe_cli(void)
{
u32_t ifl;
__asm__ __volatile__ (
"pushf\n\t"
"popl %0\n\t"
"cli\n"
: "=r" (ifl));
return ifl;
}
extern inline void safe_sti(u32_t ifl)
{
__asm__ __volatile__ (
"pushl %0\n\t"
"popf\n"
: : "r" (ifl)
);
}
extern inline void __clear (void * dst, unsigned len)
{
u32_t tmp;
__asm__ __volatile__ (
// "xorl %%eax, %%eax \n\t"
"cld \n\t"
"rep stosb \n"
:"=c"(tmp),"=D"(tmp)
:"a"(0),"c"(len),"D"(dst));
__asm__ __volatile__ ("":::"ecx","edi");
};
extern inline void out8(const u16_t port, const u8_t val)
{
__asm__ __volatile__
("outb %1, %0\n" : : "dN"(port), "a"(val));
}
extern inline void out16(const u16_t port, const u16_t val)
{
__asm__ __volatile__
("outw %1, %0\n" : : "dN"(port), "a"(val));
}
extern inline void out32(const u16_t port, const u32_t val)
{
__asm__ __volatile__
("outl %1, %0\n" : : "dN"(port), "a"(val));
}
extern inline u16_t in16(const u16_t port)
{
u16_t tmp;
__asm__ __volatile__
("inw %1, %0\n" : "=a"(tmp) : "dN"(port));
return tmp;
};
extern inline u32_t in32(const u16_t port)
{
u32_t tmp;
__asm__ __volatile__
("inl %1, %0\n" : "=a"(tmp) : "dN"(port));
return tmp;
};
extern inline void delay(int time)
{
__asm__ __volatile__ (
"call *__imp__Delay"
::"b" (time));
__asm__ __volatile__ (
"":::"ebx");
}

View File

@ -0,0 +1,24 @@
#define NULL (void*)0
typedef unsigned char u8_t;
typedef unsigned short int u16_t;
typedef unsigned int u32_t;
typedef unsigned long long u64_t;
typedef signed char i8_t;
typedef signed short int i16_t;
typedef unsigned int addr_t;
typedef unsigned int size_t;
typedef unsigned int count_t;
typedef unsigned int eflags_t;
typedef unsigned int Bool;
#define TRUE (Bool)1
#define FALSE (Bool)0

View File

@ -0,0 +1,577 @@
/*
* This file holds USB constants and structures that are needed for
* USB device APIs. These are used by the USB device model, which is
* defined in chapter 9 of the USB 2.0 specification and in the
* Wireless USB 1.0 (spread around). Linux has several APIs in C that
* need these:
*
* - the master/host side Linux-USB kernel driver API;
* - the "usbfs" user space API; and
* - the Linux "gadget" slave/device/peripheral side driver API.
*
* USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
* act either as a USB master/host or as a USB slave/device. That means
* the master and slave side APIs benefit from working well together.
*
* There's also "Wireless USB", using low power short range radios for
* peripheral interconnection but otherwise building on the USB framework.
*
* Note all descriptors are declared '__attribute__((packed))' so that:
*
* [a] they never get padded, either internally (USB spec writers
* probably handled that) or externally;
*
* [b] so that accessing bigger-than-a-bytes fields will never
* generate bus errors on any platform, even when the location of
* its descriptor inside a bundle isn't "naturally aligned", and
*
* [c] for consistency, removing all doubt even when it appears to
* someone that the two other points are non-issues for that
* particular descriptor type.
*/
#ifndef __LINUX_USB_CH9_H
#define __LINUX_USB_CH9_H
#include <linux/types.h> /* __u8 etc */
/*-------------------------------------------------------------------------*/
/* CONTROL REQUEST SUPPORT */
/*
* USB directions
*
* This bit flag is used in endpoint descriptors' bEndpointAddress field.
* It's also one of three fields in control requests bRequestType.
*/
#define USB_DIR_OUT 0 /* to device */
#define USB_DIR_IN 0x80 /* to host */
/*
* USB types, the second of three bRequestType fields
*/
#define USB_TYPE_MASK (0x03 << 5)
#define USB_TYPE_STANDARD (0x00 << 5)
#define USB_TYPE_CLASS (0x01 << 5)
#define USB_TYPE_VENDOR (0x02 << 5)
#define USB_TYPE_RESERVED (0x03 << 5)
/*
* USB recipients, the third of three bRequestType fields
*/
#define USB_RECIP_MASK 0x1f
#define USB_RECIP_DEVICE 0x00
#define USB_RECIP_INTERFACE 0x01
#define USB_RECIP_ENDPOINT 0x02
#define USB_RECIP_OTHER 0x03
/* From Wireless USB 1.0 */
#define USB_RECIP_PORT 0x04
#define USB_RECIP_RPIPE 0x05
/*
* Standard requests, for the bRequest field of a SETUP packet.
*
* These are qualified by the bRequestType field, so that for example
* TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
* by a GET_STATUS request.
*/
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */
#define USB_REQ_GET_ENCRYPTION 0x0E
#define USB_REQ_RPIPE_ABORT 0x0E
#define USB_REQ_SET_HANDSHAKE 0x0F
#define USB_REQ_RPIPE_RESET 0x0F
#define USB_REQ_GET_HANDSHAKE 0x10
#define USB_REQ_SET_CONNECTION 0x11
#define USB_REQ_SET_SECURITY_DATA 0x12
#define USB_REQ_GET_SECURITY_DATA 0x13
#define USB_REQ_SET_WUSB_DATA 0x14
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
#define USB_REQ_LOOPBACK_DATA_READ 0x16
#define USB_REQ_SET_INTERFACE_DS 0x17
/*
* USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
* are read as a bit array returned by USB_REQ_GET_STATUS. (So there
* are at most sixteen features of each type.)
*/
#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */
#define USB_DEVICE_BATTERY 2 /* (wireless) */
#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */
#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/
#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */
#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */
#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
/**
* struct usb_ctrlrequest - SETUP data for a USB device control request
* @bRequestType: matches the USB bmRequestType field
* @bRequest: matches the USB bRequest field
* @wValue: matches the USB wValue field (le16 byte order)
* @wIndex: matches the USB wIndex field (le16 byte order)
* @wLength: matches the USB wLength field (le16 byte order)
*
* This structure is used to send control requests to a USB device. It matches
* the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the
* USB spec for a fuller description of the different fields, and what they are
* used for.
*
* Note that the driver for any interface can issue control requests.
* For most devices, interfaces don't coordinate with each other, so
* such requests may be made at any time.
*/
struct usb_ctrlrequest {
__u8 bRequestType;
__u8 bRequest;
__le16 wValue;
__le16 wIndex;
__le16 wLength;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/*
* STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
* (rarely) accepted by SET_DESCRIPTOR.
*
* Note that all multi-byte values here are encoded in little endian
* byte order "on the wire". But when exposed through Linux-USB APIs,
* they've been converted to cpu byte order.
*/
/*
* Descriptor types ... USB 2.0 spec table 9.5
*/
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
#define USB_DT_STRING 0x03
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
#define USB_DT_DEVICE_QUALIFIER 0x06
#define USB_DT_OTHER_SPEED_CONFIG 0x07
#define USB_DT_INTERFACE_POWER 0x08
/* these are from a minor usb 2.0 revision (ECN) */
#define USB_DT_OTG 0x09
#define USB_DT_DEBUG 0x0a
#define USB_DT_INTERFACE_ASSOCIATION 0x0b
/* these are from the Wireless USB spec */
#define USB_DT_SECURITY 0x0c
#define USB_DT_KEY 0x0d
#define USB_DT_ENCRYPTION_TYPE 0x0e
#define USB_DT_BOS 0x0f
#define USB_DT_DEVICE_CAPABILITY 0x10
#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
#define USB_DT_WIRE_ADAPTER 0x21
#define USB_DT_RPIPE 0x22
/* conventional codes for class-specific descriptors */
#define USB_DT_CS_DEVICE 0x21
#define USB_DT_CS_CONFIG 0x22
#define USB_DT_CS_STRING 0x23
#define USB_DT_CS_INTERFACE 0x24
#define USB_DT_CS_ENDPOINT 0x25
/* All standard descriptors have these 2 fields at the beginning */
struct usb_descriptor_header {
__u8 bLength;
__u8 bDescriptorType;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_DEVICE: Device descriptor */
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__le16 idVendor;
__le16 idProduct;
__le16 bcdDevice;
__u8 iManufacturer;
__u8 iProduct;
__u8 iSerialNumber;
__u8 bNumConfigurations;
} __attribute__ ((packed));
#define USB_DT_DEVICE_SIZE 18
/*
* Device and/or Interface Class codes
* as found in bDeviceClass or bInterfaceClass
* and defined by www.usb.org documents
*/
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
#define USB_CLASS_AUDIO 1
#define USB_CLASS_COMM 2
#define USB_CLASS_HID 3
#define USB_CLASS_PHYSICAL 5
#define USB_CLASS_STILL_IMAGE 6
#define USB_CLASS_PRINTER 7
#define USB_CLASS_MASS_STORAGE 8
#define USB_CLASS_HUB 9
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
#define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPEC 0xfe
#define USB_CLASS_VENDOR_SPEC 0xff
/*-------------------------------------------------------------------------*/
/* USB_DT_CONFIG: Configuration descriptor information.
*
* USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
* descriptor type is different. Highspeed-capable devices can look
* different depending on what speed they're currently running. Only
* devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
* descriptors.
*/
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue;
__u8 iConfiguration;
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
#define USB_DT_CONFIG_SIZE 9
/* from config descriptor bmAttributes */
#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */
#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */
#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */
#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */
/*-------------------------------------------------------------------------*/
/* USB_DT_STRING: String descriptor */
struct usb_string_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wData[1]; /* UTF-16LE encoded */
} __attribute__ ((packed));
/* note that "string" zero is special, it holds language codes that
* the device supports, not Unicode characters.
*/
/*-------------------------------------------------------------------------*/
/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface;
} __attribute__ ((packed));
#define USB_DT_INTERFACE_SIZE 9
/*-------------------------------------------------------------------------*/
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
#define USB_DT_ENDPOINT_SIZE 7
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
/*
* Endpoints
*/
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
#define USB_ENDPOINT_DIR_MASK 0x80
#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
#define USB_ENDPOINT_XFER_CONTROL 0
#define USB_ENDPOINT_XFER_ISOC 1
#define USB_ENDPOINT_XFER_BULK 2
#define USB_ENDPOINT_XFER_INT 3
#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
/*-------------------------------------------------------------------------*/
/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
struct usb_qualifier_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
__u8 bMaxPacketSize0;
__u8 bNumConfigurations;
__u8 bRESERVED;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_OTG (from OTG 1.0a supplement) */
struct usb_otg_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bmAttributes; /* support for HNP, SRP, etc */
} __attribute__ ((packed));
/* from usb_otg_descriptor.bmAttributes */
#define USB_OTG_SRP (1 << 0)
#define USB_OTG_HNP (1 << 1) /* swap host/device roles */
/*-------------------------------------------------------------------------*/
/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */
struct usb_debug_descriptor {
__u8 bLength;
__u8 bDescriptorType;
/* bulk endpoints with 8 byte maxpacket */
__u8 bDebugInEndpoint;
__u8 bDebugOutEndpoint;
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */
struct usb_interface_assoc_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bFirstInterface;
__u8 bInterfaceCount;
__u8 bFunctionClass;
__u8 bFunctionSubClass;
__u8 bFunctionProtocol;
__u8 iFunction;
} __attribute__ ((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_SECURITY: group of wireless security descriptors, including
* encryption types available for setting up a CC/association.
*/
struct usb_security_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumEncryptionTypes;
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_KEY: used with {GET,SET}_SECURITY_DATA; only public keys
* may be retrieved.
*/
struct usb_key_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 tTKID[3];
__u8 bReserved;
__u8 bKeyData[0];
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_ENCRYPTION_TYPE: bundled in DT_SECURITY groups */
struct usb_encryption_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEncryptionType;
#define USB_ENC_TYPE_UNSECURE 0
#define USB_ENC_TYPE_WIRED 1 /* non-wireless mode */
#define USB_ENC_TYPE_CCM_1 2 /* aes128/cbc session */
#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */
__u8 bEncryptionValue; /* use in SET_ENCRYPTION */
__u8 bAuthKeyIndex;
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_BOS: group of wireless capabilities */
struct usb_bos_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumDeviceCaps;
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_DEVICE_CAPABILITY: grouped with BOS */
struct usb_dev_cap_header {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDevCapabilityType;
} __attribute__((packed));
#define USB_CAP_TYPE_WIRELESS_USB 1
struct usb_wireless_cap_descriptor { /* Ultra Wide Band */
__u8 bLength;
__u8 bDescriptorType;
__u8 bDevCapabilityType;
__u8 bmAttributes;
#define USB_WIRELESS_P2P_DRD (1 << 1)
#define USB_WIRELESS_BEACON_MASK (3 << 2)
#define USB_WIRELESS_BEACON_SELF (1 << 2)
#define USB_WIRELESS_BEACON_DIRECTED (2 << 2)
#define USB_WIRELESS_BEACON_NONE (3 << 2)
__le16 wPHYRates; /* bit rates, Mbps */
#define USB_WIRELESS_PHY_53 (1 << 0) /* always set */
#define USB_WIRELESS_PHY_80 (1 << 1)
#define USB_WIRELESS_PHY_107 (1 << 2) /* always set */
#define USB_WIRELESS_PHY_160 (1 << 3)
#define USB_WIRELESS_PHY_200 (1 << 4) /* always set */
#define USB_WIRELESS_PHY_320 (1 << 5)
#define USB_WIRELESS_PHY_400 (1 << 6)
#define USB_WIRELESS_PHY_480 (1 << 7)
__u8 bmTFITXPowerInfo; /* TFI power levels */
__u8 bmFFITXPowerInfo; /* FFI power levels */
__le16 bmBandGroup;
__u8 bReserved;
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with
* each endpoint descriptor for a wireless device
*/
struct usb_wireless_ep_comp_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bMaxBurst;
__u8 bMaxSequence;
__le16 wMaxStreamDelay;
__le16 wOverTheAirPacketSize;
__u8 bOverTheAirInterval;
__u8 bmCompAttributes;
#define USB_ENDPOINT_SWITCH_MASK 0x03 /* in bmCompAttributes */
#define USB_ENDPOINT_SWITCH_NO 0
#define USB_ENDPOINT_SWITCH_SWITCH 1
#define USB_ENDPOINT_SWITCH_SCALE 2
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless
* host and a device for connection set up, mutual authentication, and
* exchanging short lived session keys. The handshake depends on a CC.
*/
struct usb_handshake {
__u8 bMessageNumber;
__u8 bStatus;
__u8 tTKID[3];
__u8 bReserved;
__u8 CDID[16];
__u8 nonce[16];
__u8 MIC[8];
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC).
* A CC may also be set up using non-wireless secure channels (including
* wired USB!), and some devices may support CCs with multiple hosts.
*/
struct usb_connection_context {
__u8 CHID[16]; /* persistent host id */
__u8 CDID[16]; /* device id (unique w/in host context) */
__u8 CK[16]; /* connection key */
} __attribute__((packed));
/*-------------------------------------------------------------------------*/
/* USB 2.0 defines three speeds, here's how Linux identifies them */
enum usb_device_speed {
USB_SPEED_UNKNOWN = 0, /* enumerating */
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
USB_SPEED_HIGH, /* usb 2.0 */
USB_SPEED_VARIABLE, /* wireless (usb 2.5) */
};
enum usb_device_state {
/* NOTATTACHED isn't in the USB spec, and this state acts
* the same as ATTACHED ... but it's clearer this way.
*/
USB_STATE_NOTATTACHED = 0,
/* chapter 9 and authentication (wireless) device states */
USB_STATE_ATTACHED,
USB_STATE_POWERED, /* wired */
USB_STATE_UNAUTHENTICATED, /* auth */
USB_STATE_RECONNECTING, /* auth */
USB_STATE_DEFAULT, /* limited function */
USB_STATE_ADDRESS,
USB_STATE_CONFIGURED, /* most functions */
USB_STATE_SUSPENDED
/* NOTE: there are actually four different SUSPENDED
* states, returning to POWERED, DEFAULT, ADDRESS, or
* CONFIGURED respectively when SOF tokens flow again.
*/
};
#endif /* __LINUX_USB_CH9_H */

View File

@ -0,0 +1,63 @@
Bool FindPciDevice()
{
Bool retval = FALSE;
u32_t bus, last_bus;
PCITAG tag;
if( (last_bus = PciApi(1))==-1)
return retval;
for(bus=0;bus<=last_bus;bus++)
{
u32_t devfn;
for(devfn=0;devfn<256;devfn++)
{
hc_t *hc;
u32_t id;
u16_t pcicmd;
u16_t devclass;
int i;
devclass = PciRead16(bus,devfn, 0x0A);
if( devclass != 0x0C03)
continue;
pcicmd = PciRead16(bus,devfn, PCI_COMMAND);
if (! pcicmd & PCI_COMMAND_IO)
continue;
hc = (hc_t*)malloc(sizeof(hc_t));
memset(hc, 0, sizeof(hc_t));
link_initialize(&hc->link);
hc->pciId = PciRead32(bus,devfn, 0);
hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
for (i = 0; i < 6; i++)
{
u32_t base;
Bool validSize;
base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2));
if(base)
{
if (base & PCI_MAP_IO) {
hc->ioBase[i] = (addr_t)PCIGETIO(base);
hc->memType[i] = base & PCI_MAP_IO_ATTR_MASK;
} else {
hc->memBase[i] = (u32_t)PCIGETMEMORY(base);
hc->memType[i] = base & PCI_MAP_MEMORY_ATTR_MASK;
}
}
};
list_prepend(&hc->link, &hc_list);
retval = TRUE;
};
};
return retval;
};

View File

@ -0,0 +1,604 @@
#define UHCI_USBLEGSUP 0x00c0 /* legacy support */
#define UHCI_USBCMD 0 /* command register */
#define UHCI_USBINTR 4 /* interrupt register */
#define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
#define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
#define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */
#define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */
#define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */
#define UHCI_USBCMD_CONFIGURE 0x0040 /* Config Flag */
#define UHCI_USBINTR_RESUME 0x0002 /* Resume interrupt enable */
#define USBCMD 0
#define USBCMD_RS 0x0001 /* Run/Stop */
#define USBCMD_HCRESET 0x0002 /* Host reset */
#define USBCMD_GRESET 0x0004 /* Global reset */
#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
#define USBCMD_FGR 0x0010 /* Force Global Resume */
#define USBCMD_SWDBG 0x0020 /* SW Debug mode */
#define USBCMD_CF 0x0040 /* Config Flag (sw only) */
#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
#define USBSTS 2
#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
#define USBSTS_ERROR 0x0002 /* Interrupt due to error */
#define USBSTS_RD 0x0004 /* Resume Detect */
#define USBSTS_HSE 0x0008 /* Host System Error: PCI problems */
#define USBSTS_HCPE 0x0010 /* Host Controller Process Error:
* the schedule is buggy */
#define USBSTS_HCH 0x0020 /* HC Halted */
#define USBFRNUM 6
#define USBFLBASEADD 8
#define USBSOF 12
#define USBSOF_DEFAULT 64 /* Frame length is exactly 1 ms */
#define USBPORTSC1 16
#define USBPORTSC2 18
#define UHCI_RH_MAXCHILD 7
/*
* Make sure the controller is completely inactive, unable to
* generate interrupts or do DMA.
*/
void uhci_reset_hc(hc_t *hc)
{
/* Turn off PIRQ enable and SMI enable. (This also turns off the
* BIOS's USB Legacy Support.) Turn off all the R/WC bits too.
*/
pciWriteWord(hc->PciTag, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC);
/* Reset the HC - this will force us to get a
* new notification of any already connected
* ports due to the virtual disconnect that it
* implies.
*/
out16(hc->iobase + UHCI_USBCMD, UHCI_USBCMD_HCRESET);
__asm__ __volatile__ ("":::"memory");
delay(20/10);
if (in16(hc->iobase + UHCI_USBCMD) & UHCI_USBCMD_HCRESET)
dbgprintf("HCRESET not completed yet!\n");
/* Just to be safe, disable interrupt requests and
* make sure the controller is stopped.
*/
out16(hc->iobase + UHCI_USBINTR, 0);
out16(hc->iobase + UHCI_USBCMD, 0);
};
int uhci_check_and_reset_hc(hc_t *hc)
{
u16_t legsup;
unsigned int cmd, intr;
/*
* When restarting a suspended controller, we expect all the
* settings to be the same as we left them:
*
* PIRQ and SMI disabled, no R/W bits set in USBLEGSUP;
* Controller is stopped and configured with EGSM set;
* No interrupts enabled except possibly Resume Detect.
*
* If any of these conditions are violated we do a complete reset.
*/
legsup = pciReadWord(hc->PciTag, UHCI_USBLEGSUP);
if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) {
dbgprintf("%s: legsup = 0x%04x\n",__FUNCTION__, legsup);
goto reset_needed;
}
cmd = in16(hc->iobase + UHCI_USBCMD);
if ( (cmd & UHCI_USBCMD_RUN) ||
!(cmd & UHCI_USBCMD_CONFIGURE) ||
!(cmd & UHCI_USBCMD_EGSM))
{
dbgprintf("%s: cmd = 0x%04x\n", __FUNCTION__, cmd);
goto reset_needed;
}
intr = in16(hc->iobase + UHCI_USBINTR);
if (intr & (~UHCI_USBINTR_RESUME))
{
dbgprintf("%s: intr = 0x%04x\n", __FUNCTION__, intr);
goto reset_needed;
}
return 0;
reset_needed:
dbgprintf("Performing full reset\n");
uhci_reset_hc(hc);
return 1;
}
Bool init_hc(hc_t *hc)
{
int port;
u32_t ifl;
u16_t dev_status;
int i;
dbgprintf("\n\ninit uhci %x\n\n", hc->pciId);
for(i=0;i<6;i++)
{
if(hc->ioBase[i]){
hc->iobase = hc->ioBase[i];
// dbgprintf("Io base_%d 0x%x\n", i,hc->ioBase[i]);
break;
};
};
/* The UHCI spec says devices must have 2 ports, and goes on to say
* they may have more but gives no way to determine how many there
* are. However according to the UHCI spec, Bit 7 of the port
* status and control register is always set to 1. So we try to
* use this to our advantage. Another common failure mode when
* a nonexistent register is addressed is to return all ones, so
* we test for that also.
*/
for (port = 0; port < 2; port++)
{
u32_t status;
status = in16(hc->iobase + USBPORTSC1 + (port * 2));
dbgprintf("port%d status %x\n", port, status);
if (!(status & 0x0080) || status == 0xffff)
break;
}
dbgprintf("detected %d ports\n\n", port);
hc->numports = port;
/* Kick BIOS off this hardware and reset if the controller
* isn't already safely quiescent.
*/
uhci_check_and_reset_hc(hc);
hc->frame_base = (u32_t*)KernelAlloc(4096);
hc->frame_dma = GetPgAddr(hc->frame_base);
hc->frame_number = 0;
qh_t *qh = alloc_qh();
qh->qlink = 1;
qh->qelem = 1;
hc->qh1 = qh;
// dbgprintf("alloc qh %x dma %x\n", qh, qh->dma);
for(i=0; i<1024; i++)
hc->frame_base[i] = qh->dma | 2;
/* Set the frame length to the default: 1 ms exactly */
out8(hc->iobase + USBSOF, USBSOF_DEFAULT);
/* Store the frame list base address */
out32(hc->iobase + USBFLBASEADD, hc->frame_dma);
/* Set the current frame number */
out16(hc->iobase + USBFRNUM, 0);
out16(hc->iobase + USBSTS, 0x3F);
out16(hc->iobase + USBCMD, USBCMD_RS | USBCMD_CF |
USBCMD_MAXP);
for (port = 0; port < hc->numports; ++port)
out16(hc->iobase + USBPORTSC1 + (port * 2), 0x200);
delay(100/10);
for (port = 0; port < 2; ++port)
{
time_t timeout;
u32_t status = in16(hc->iobase + USBPORTSC1 + (port * 2));
dbgprintf("port%d status %x\n", port, status);
out16(hc->iobase + USBPORTSC1 + (port * 2), 0);
timeout = 100/10;
while(timeout--)
{
delay(10/10);
status = in16(hc->iobase + USBPORTSC1 + (port * 2));
if(status & 1)
{
udev_t *dev = malloc(sizeof(udev_t));
out16(hc->iobase + USBPORTSC1 + (port * 2), 0x0E);
delay(20/10);
dbgprintf("enable port\n");
status = in16(hc->iobase + USBPORTSC1 + (port * 2));
dbgprintf("port%d status %x\n", port, status);
link_initialize(&dev->link);
dev->id = 0;
dev->host = hc;
dev->addr = 0;
dev->port = port;
dev->ep0_size = 8;
dev->status = status;
dbgprintf("port%d connected", port);
if(status & 4)
dbgprintf(" enabled");
else
dbgprintf(" disabled");
if(status & 0x100){
dev->speed = 0x4000000;
dbgprintf(" low speed\n");
} else {
dev->speed = 0;
dbgprintf(" full speed\n");
};
if(set_address(dev)) {
list_prepend(&dev->link, &newdev_list);
hc->port_map |= 1<<port;
}
else {
free(dev);
out16(hc->iobase + USBPORTSC1 + (port * 2), 0);
}
break;
};
};
};
return TRUE;
};
u16_t __attribute__((aligned(16)))
req_descr[4] = {0x0680,0x0100,0x0000,8};
/*
IN(69) OUT(E1) SETUP(2D)
SETUP(0) IN(1)
SETUP(0) OUT(1) OUT(0) OUT(1)...IN(1)
SETUP(0) IN(1) IN(0) IN(1)...OUT(0)
*/
Bool set_address(udev_t *dev)
{
static udev_id = 0;
static udev_addr = 0;
static u16_t __attribute__((aligned(16)))
req_addr[4] = {0x0500,0x0001,0x0000,0x0000};
static u16_t __attribute__((aligned(16)))
req_descr[4] = {0x0680,0x0100,0x0000,8};
static u32_t data[2] __attribute__((aligned(16)));
qh_t *qh;
td_t *td0, *td1, *td2;
u32_t dev_status;
count_t timeout;
int address;
address = ++udev_addr;
req_addr[1] = address;
if( !ctrl_request(dev, &req_addr, DOUT, NULL, 0))
return FALSE;
dev->addr = address;
dev->id = (++udev_id << 8) | address;
dbgprintf("set address %d\n", address);
data[0] = 0;
data[1] = 0;
if( !ctrl_request(dev, &req_descr, DIN, data, 8))
return FALSE;
dev_descr_t *descr = (dev_descr_t*)&data;
dev->ep0_size = descr->bMaxPacketSize0;
return TRUE;
}
request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir,
void *data, size_t req_size)
{
td_t *td, *td_prev;
addr_t data_dma;
request_t *rq = (request_t*)malloc(sizeof(request_t));
link_initialize(&rq->link);
rq->td_head = 0;
rq->td_tail = 0;
rq->data = (addr_t)data;
rq->size = req_size;
rq->dev = dev;
if(data)
data_dma = DMA(data);
td_prev = NULL;
while(req_size >= enp->size)
{
td = alloc_td();
td->link = 1;
if(rq->td_head == NULL)
rq->td_head = td;
if( td_prev )
td_prev->link = td->dma | 4;
td->status = 0x00800000 | dev->speed;
td->token = TOKEN(enp->size,enp->toggle,enp->address,
dev->addr,dir);
td->buffer = data_dma;
td->bk = td_prev;
td_prev = td;
data_dma+= enp->size;
req_size-= enp->size;
enp->toggle ^= DATA1;
}
if(req_size)
{
td = alloc_td();
td->link = 1;
if(rq->td_head == NULL)
rq->td_head = td;
if( td_prev )
td_prev->link = td->dma | 4;
td->status = 0x00800000 | dev->speed;
td->token = TOKEN( req_size, enp->toggle, enp->address,
dev->addr, dir);
td->buffer = data_dma;
td->bk = td_prev;
enp->toggle ^= DATA1;
}
rq->td_tail = td;
/*
dbgprintf("create request %x\n"
"head %x\n"
"tail %x\n"
"data %x\n"
"size %x\n",
rq, rq->td_head, rq->td_tail,
rq->data, rq->size);
*/
return rq;
}
Bool ctrl_request(udev_t *dev, void *req, u32_t pid,
void *data, size_t req_size)
{
size_t packet_size = dev->ep0_size;
size_t size = req_size;
u32_t toggle = DATA1;
td_t *td0, *td, *td_prev;
qh_t *qh;
addr_t data_dma = 0;
Bool retval;
td0 = alloc_td();
td0->status = 0x00800000 | dev->speed;
td0->token = TOKEN( 8, DATA0, 0, dev->addr, 0x2D);
td0->buffer = DMA(req);
td0->bk = NULL;
if(data)
data_dma = DMA(data);
td_prev = td0;
while(size >= packet_size)
{
td = alloc_td();
td_prev->link = td->dma | 4;
td->status = 0x00800000 | dev->speed;
td->token = TOKEN(packet_size, toggle, 0,dev->addr, pid);
td->buffer = data_dma;
td->bk = td_prev;
td_prev = td;
data_dma+= packet_size;
size-= packet_size;
toggle ^= DATA1;
}
if(size)
{
td = alloc_td();
td_prev->link = td->dma | 4;
td->status = 0x00800000 | dev->speed;
td->token = ((size-1)<<21)|toggle|(dev->addr<<8)|pid;
td->buffer = data_dma;
td->bk = td_prev;
td_prev = td;
data_dma+= packet_size;
size-= packet_size;
toggle ^= DATA1;
}
td = alloc_td();
td_prev->link = td->dma | 4;
pid = (pid == DIN) ? DOUT : DIN;
td->link = 1;
td->status = 0x00800000 | dev->speed;
td->token = (0x7FF<<21)|DATA1|(dev->addr<<8)|pid;
td->buffer = 0;
td->bk = td_prev;
qh = dev->host->qh1;
qh->qelem = td0->dma;
__asm__ __volatile__ ("":::"memory");
count_t timeout = 25;
while(timeout--){
delay(10/10);
if( !(td->status & TD_CTRL_ACTIVE))
break;
}
if( (td0->status & TD_ANY_ERROR) ||
(td_prev->status & TD_ANY_ERROR) ||
(td->status & TD_ANY_ERROR))
{
u32_t dev_status = in16(dev->host->iobase + USBSTS);
dbgprintf("\nframe %x, cmd %x status %x\n",
in16(dev->host->iobase + USBFRNUM),
in16(dev->host->iobase + USBCMD),
dev_status);
dbgprintf("td0 status %x\n",td0->status);
dbgprintf("td_prev status %x\n",td_prev->status);
dbgprintf("td status %x\n",td->status);
dbgprintf("qh %x \n", qh->qelem);
retval = FALSE;
} else retval = TRUE;
do
{
td_prev = td->bk;
free_td(td);
td = td_prev;
}while( td != NULL);
return retval;
};
Bool init_device(udev_t *dev)
{
static u16_t __attribute__((aligned(16)))
req_descr[4] = {0x0680,0x0100,0x0000,18};
static u16_t __attribute__((aligned(16)))
req_conf[4] = {0x0680,0x0200,0x0000,9};
static dev_descr_t __attribute__((aligned(16))) descr;
interface_descr_t *interface;
u32_t data[8];
u8_t *dptr;
conf_descr_t *conf;
dbgprintf("\ninit device %x, host %x, port %d\n\n",
dev->id, dev->host->pciId, dev->port);
if( !ctrl_request(dev, req_descr, DIN, &descr, 18))
return;
dev->dev_descr = descr;
dbgprintf("device descriptor:\n\n"
"bLength %d\n"
"bDescriptorType %d\n"
"bcdUSB %x\n"
"bDeviceClass %x\n"
"bDeviceSubClass %x\n"
"bDeviceProtocol %x\n"
"bMaxPacketSize0 %d\n"
"idVendor %x\n"
"idProduct %x\n"
"bcdDevice %x\n"
"iManufacturer %x\n"
"iProduct %x\n"
"iSerialNumber %x\n"
"bNumConfigurations %d\n\n",
descr.bLength, descr.bDescriptorType,
descr.bcdUSB, descr.bDeviceClass,
descr.bDeviceSubClass, descr.bDeviceProtocol,
descr.bMaxPacketSize0, descr.idVendor,
descr.idProduct, descr.bcdDevice,
descr.iManufacturer, descr.iProduct,
descr.iSerialNumber, descr.bNumConfigurations);
req_conf[3] = 8;
if( !ctrl_request(dev, req_conf, DIN, &data, 8))
return;
conf = (conf_descr_t*)&data;
size_t conf_size = conf->wTotalLength;
req_conf[3] = conf_size;
conf = malloc(conf_size);
if( !ctrl_request(dev, req_conf, DIN, conf, conf_size))
return;
dptr = (u8_t*)conf;
dptr+= conf->bLength;
dbgprintf("configuration descriptor\n\n"
"bLength %d\n"
"bDescriptorType %d\n"
"wTotalLength %d\n"
"bNumInterfaces %d\n"
"bConfigurationValue %x\n"
"iConfiguration %d\n"
"bmAttributes %x\n"
"bMaxPower %dmA\n\n",
conf->bLength,
conf->bDescriptorType,
conf->wTotalLength,
conf->bNumInterfaces,
conf->bConfigurationValue,
conf->iConfiguration,
conf->bmAttributes,
conf->bMaxPower*2);
interface = (interface_descr_t*)dptr;
switch(interface->bInterfaceClass)
{
case USB_CLASS_AUDIO:
dbgprintf( "audio device\n");
break;
case USB_CLASS_HID:
dev->conf = conf;
list_remove(&dev->link);
return init_hid(dev);
case USB_CLASS_PRINTER:
dbgprintf("printer\n");
break;
case USB_CLASS_MASS_STORAGE:
dbgprintf("mass storage device\n");
break;
case USB_CLASS_HUB:
dbgprintf("hub device\n");
break;
default:
dbgprintf("unknown device\n");
};
};

View File

@ -0,0 +1,523 @@
#ifndef __HID_H
#define __HID_H
/*
* $Id: hid.h,v 1.24 2001/12/27 10:37:41 vojtech Exp $
*
* Copyright (c) 1999 Andreas Gal
* Copyright (c) 2000-2001 Vojtech Pavlik
* Copyright (c) 2006-2007 Jiri Kosina
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/input.h>
/*
* USB HID (Human Interface Device) interface class code
*/
#define USB_INTERFACE_CLASS_HID 3
/*
* USB HID interface subclass and protocol codes
*/
#define USB_INTERFACE_SUBCLASS_BOOT 1
#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
#define USB_INTERFACE_PROTOCOL_MOUSE 2
/*
* HID class requests
*/
#define HID_REQ_GET_REPORT 0x01
#define HID_REQ_GET_IDLE 0x02
#define HID_REQ_GET_PROTOCOL 0x03
#define HID_REQ_SET_REPORT 0x09
#define HID_REQ_SET_IDLE 0x0A
#define HID_REQ_SET_PROTOCOL 0x0B
/*
* HID class descriptor types
*/
#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
/*
* We parse each description item into this structure. Short items data
* values are expanded to 32-bit signed int, long items contain a pointer
* into the data area.
*/
struct hid_item {
unsigned format;
__u8 size;
__u8 type;
__u8 tag;
union {
__u8 u8;
__s8 s8;
__u16 u16;
__s16 s16;
__u32 u32;
__s32 s32;
__u8 *longdata;
} data;
};
/*
* HID report item format
*/
#define HID_ITEM_FORMAT_SHORT 0
#define HID_ITEM_FORMAT_LONG 1
/*
* Special tag indicating long items
*/
#define HID_ITEM_TAG_LONG 15
/*
* HID report descriptor item type (prefix bit 2,3)
*/
#define HID_ITEM_TYPE_MAIN 0
#define HID_ITEM_TYPE_GLOBAL 1
#define HID_ITEM_TYPE_LOCAL 2
#define HID_ITEM_TYPE_RESERVED 3
/*
* HID report descriptor main item tags
*/
#define HID_MAIN_ITEM_TAG_INPUT 8
#define HID_MAIN_ITEM_TAG_OUTPUT 9
#define HID_MAIN_ITEM_TAG_FEATURE 11
#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10
#define HID_MAIN_ITEM_TAG_END_COLLECTION 12
/*
* HID report descriptor main item contents
*/
#define HID_MAIN_ITEM_CONSTANT 0x001
#define HID_MAIN_ITEM_VARIABLE 0x002
#define HID_MAIN_ITEM_RELATIVE 0x004
#define HID_MAIN_ITEM_WRAP 0x008
#define HID_MAIN_ITEM_NONLINEAR 0x010
#define HID_MAIN_ITEM_NO_PREFERRED 0x020
#define HID_MAIN_ITEM_NULL_STATE 0x040
#define HID_MAIN_ITEM_VOLATILE 0x080
#define HID_MAIN_ITEM_BUFFERED_BYTE 0x100
/*
* HID report descriptor collection item types
*/
#define HID_COLLECTION_PHYSICAL 0
#define HID_COLLECTION_APPLICATION 1
#define HID_COLLECTION_LOGICAL 2
/*
* HID report descriptor global item tags
*/
#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0
#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1
#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2
#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3
#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4
#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5
#define HID_GLOBAL_ITEM_TAG_UNIT 6
#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7
#define HID_GLOBAL_ITEM_TAG_REPORT_ID 8
#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9
#define HID_GLOBAL_ITEM_TAG_PUSH 10
#define HID_GLOBAL_ITEM_TAG_POP 11
/*
* HID report descriptor local item tags
*/
#define HID_LOCAL_ITEM_TAG_USAGE 0
#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1
#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4
#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5
#define HID_LOCAL_ITEM_TAG_STRING_INDEX 7
#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8
#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9
#define HID_LOCAL_ITEM_TAG_DELIMITER 10
/*
* HID usage tables
*/
#define HID_USAGE_PAGE 0xffff0000
#define HID_UP_UNDEFINED 0x00000000
#define HID_UP_GENDESK 0x00010000
#define HID_UP_SIMULATION 0x00020000
#define HID_UP_KEYBOARD 0x00070000
#define HID_UP_LED 0x00080000
#define HID_UP_BUTTON 0x00090000
#define HID_UP_ORDINAL 0x000a0000
#define HID_UP_CONSUMER 0x000c0000
#define HID_UP_DIGITIZER 0x000d0000
#define HID_UP_PID 0x000f0000
#define HID_UP_HPVENDOR 0xff7f0000
#define HID_UP_MSVENDOR 0xff000000
#define HID_UP_CUSTOM 0x00ff0000
#define HID_UP_LOGIVENDOR 0xffbc0000
#define HID_USAGE 0x0000ffff
#define HID_GD_POINTER 0x00010001
#define HID_GD_MOUSE 0x00010002
#define HID_GD_JOYSTICK 0x00010004
#define HID_GD_GAMEPAD 0x00010005
#define HID_GD_KEYBOARD 0x00010006
#define HID_GD_KEYPAD 0x00010007
#define HID_GD_MULTIAXIS 0x00010008
#define HID_GD_X 0x00010030
#define HID_GD_Y 0x00010031
#define HID_GD_Z 0x00010032
#define HID_GD_RX 0x00010033
#define HID_GD_RY 0x00010034
#define HID_GD_RZ 0x00010035
#define HID_GD_SLIDER 0x00010036
#define HID_GD_DIAL 0x00010037
#define HID_GD_WHEEL 0x00010038
#define HID_GD_HATSWITCH 0x00010039
#define HID_GD_BUFFER 0x0001003a
#define HID_GD_BYTECOUNT 0x0001003b
#define HID_GD_MOTION 0x0001003c
#define HID_GD_START 0x0001003d
#define HID_GD_SELECT 0x0001003e
#define HID_GD_VX 0x00010040
#define HID_GD_VY 0x00010041
#define HID_GD_VZ 0x00010042
#define HID_GD_VBRX 0x00010043
#define HID_GD_VBRY 0x00010044
#define HID_GD_VBRZ 0x00010045
#define HID_GD_VNO 0x00010046
#define HID_GD_FEATURE 0x00010047
#define HID_GD_UP 0x00010090
#define HID_GD_DOWN 0x00010091
#define HID_GD_RIGHT 0x00010092
#define HID_GD_LEFT 0x00010093
/*
* HID report types --- Ouch! HID spec says 1 2 3!
*/
#define HID_INPUT_REPORT 0
#define HID_OUTPUT_REPORT 1
#define HID_FEATURE_REPORT 2
/*
* HID device quirks.
*/
#define HID_QUIRK_INVERT 0x00000001
#define HID_QUIRK_NOTOUCH 0x00000002
#define HID_QUIRK_IGNORE 0x00000004
#define HID_QUIRK_NOGET 0x00000008
#define HID_QUIRK_HIDDEV 0x00000010
#define HID_QUIRK_BADPAD 0x00000020
#define HID_QUIRK_MULTI_INPUT 0x00000040
#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080
#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100
#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200
#define HID_QUIRK_MIGHTYMOUSE 0x00000400
#define HID_QUIRK_CYMOTION 0x00000800
#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
#define HID_QUIRK_INVERT_HWHEEL 0x00004000
#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000
#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000
#define HID_QUIRK_IGNORE_MOUSE 0x00040000
#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000
#define HID_QUIRK_LOGITECH_S510_DESCRIPTOR 0x00100000
#define HID_QUIRK_DUPLICATE_USAGES 0x00200000
/*
* This is the global environment of the parser. This information is
* persistent for main-items. The global environment can be saved and
* restored with PUSH/POP statements.
*/
struct hid_global {
unsigned usage_page;
__s32 logical_minimum;
__s32 logical_maximum;
__s32 physical_minimum;
__s32 physical_maximum;
__s32 unit_exponent;
unsigned unit;
unsigned report_id;
unsigned report_size;
unsigned report_count;
};
/*
* This is the local environment. It is persistent up the next main-item.
*/
#define HID_MAX_DESCRIPTOR_SIZE 4096
#define HID_MAX_USAGES 8192
#define HID_DEFAULT_NUM_COLLECTIONS 16
struct hid_local {
unsigned usage[HID_MAX_USAGES]; /* usage array */
unsigned collection_index[HID_MAX_USAGES]; /* collection index array */
unsigned usage_index;
unsigned usage_minimum;
unsigned delimiter_depth;
unsigned delimiter_branch;
};
/*
* This is the collection stack. We climb up the stack to determine
* application and function of each field.
*/
struct hid_collection {
unsigned type;
unsigned usage;
unsigned level;
};
struct hid_usage {
unsigned hid; /* hid usage code */
unsigned collection_index; /* index into collection array */
/* hidinput data */
__u16 code; /* input driver code */
__u8 type; /* input driver type */
__s8 hat_min; /* hat switch fun */
__s8 hat_max; /* ditto */
__s8 hat_dir; /* ditto */
};
struct hid_input;
struct hid_field {
unsigned physical; /* physical usage for this field */
unsigned logical; /* logical usage for this field */
unsigned application; /* application usage for this field */
struct hid_usage *usage; /* usage table for this function */
unsigned maxusage; /* maximum usage index */
unsigned flags; /* main-item flags (i.e. volatile,array,constant) */
unsigned report_offset; /* bit offset in the report */
unsigned report_size; /* size of this field in the report */
unsigned report_count; /* number of this field in the report */
unsigned report_type; /* (input,output,feature) */
__s32 *value; /* last known value(s) */
__s32 logical_minimum;
__s32 logical_maximum;
__s32 physical_minimum;
__s32 physical_maximum;
__s32 unit_exponent;
unsigned unit;
struct hid_report *report; /* associated report */
unsigned index; /* index into report->field[] */
/* hidinput data */
struct hid_input *hidinput; /* associated input structure */
__u16 dpad; /* dpad input code */
};
#define HID_MAX_FIELDS 64
struct hid_report {
struct list_head list;
unsigned id; /* id of this report */
unsigned type; /* report type */
struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
unsigned maxfield; /* maximum valid field index */
unsigned size; /* size of the report (bits) */
struct hid_device *device; /* associated device */
};
struct hid_report_enum {
unsigned numbered;
struct list_head report_list;
struct hid_report *report_id_hash[256];
};
#define HID_REPORT_TYPES 3
#define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */
#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */
#define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */
#define HID_OUTPUT_FIFO_SIZE 64
struct hid_control_fifo {
unsigned char dir;
struct hid_report *report;
};
#define HID_CLAIMED_INPUT 1
#define HID_CLAIMED_HIDDEV 2
#define HID_CTRL_RUNNING 1
#define HID_OUT_RUNNING 2
#define HID_IN_RUNNING 3
#define HID_RESET_PENDING 4
#define HID_SUSPENDED 5
#define HID_CLEAR_HALT 6
struct hid_input {
struct list_head list;
struct hid_report *report;
struct input_dev *input;
};
struct hid_device { /* device report descriptor */
__u8 *rdesc;
unsigned rsize;
struct hid_collection *collection; /* List of HID collections */
unsigned collection_size; /* Number of allocated hid_collections */
unsigned maxcollection; /* Number of parsed collections */
unsigned maxapplication; /* Number of applications */
unsigned short bus; /* BUS ID */
unsigned short vendor; /* Vendor ID */
unsigned short product; /* Product ID */
unsigned version; /* HID version */
unsigned country; /* HID country */
struct hid_report_enum report_enum[HID_REPORT_TYPES];
struct device *dev; /* device */
unsigned claimed; /* Claimed by hidinput, hiddev? */
unsigned quirks; /* Various quirks the device can pull on us */
struct list_head inputs; /* The list of inputs */
void *hiddev; /* The hiddev structure */
int minor; /* Hiddev minor number */
wait_queue_head_t wait; /* For sleeping */
int open; /* is the device open by anyone? */
char name[128]; /* Device name */
char phys[64]; /* Device physical location */
char uniq[64]; /* Device unique identifier (serial #) */
void *driver_data;
/* device-specific function pointers */
int (*hidinput_input_event) (struct input_dev *, unsigned int, unsigned int, int);
int (*hid_open) (struct hid_device *);
void (*hid_close) (struct hid_device *);
/* hiddev event handler */
void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
struct hid_usage *, __s32);
void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
#endif
};
#define HID_GLOBAL_STACK_SIZE 4
#define HID_COLLECTION_STACK_SIZE 4
struct hid_parser {
struct hid_global global;
struct hid_global global_stack[HID_GLOBAL_STACK_SIZE];
unsigned global_stack_ptr;
struct hid_local local;
unsigned collection_stack[HID_COLLECTION_STACK_SIZE];
unsigned collection_stack_ptr;
struct hid_device *device;
};
struct hid_class_descriptor {
__u8 bDescriptorType;
__u16 wDescriptorLength;
} __attribute__ ((packed));
struct hid_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u16 bcdHID;
__u8 bCountryCode;
__u8 bNumDescriptors;
struct hid_class_descriptor desc[1];
} __attribute__ ((packed));
/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
/* We ignore a few input applications that are not widely used */
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
/* HID core API */
extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
extern int hidinput_connect(struct hid_device *);
extern void hidinput_disconnect(struct hid_device *);
int hid_set_field(struct hid_field *, unsigned, __s32);
int hid_input_report(struct hid_device *, int type, u8 *, int, int);
int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt);
void hid_output_report(struct hid_report *report, __u8 *data);
void hid_free_device(struct hid_device *device);
struct hid_device *hid_parse_report(__u8 *start, unsigned size);
#ifdef CONFIG_HID_FF
int hid_ff_init(struct hid_device *hid);
int hid_lgff_init(struct hid_device *hid);
int hid_plff_init(struct hid_device *hid);
int hid_tmff_init(struct hid_device *hid);
int hid_zpff_init(struct hid_device *hid);
#ifdef CONFIG_HID_PID
int hid_pidff_init(struct hid_device *hid);
#else
static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
#endif
#else
static inline int hid_ff_init(struct hid_device *hid) { return -1; }
#endif
#ifdef DEBUG
#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \
__FILE__ , ## arg)
#else
#define dbg(format, arg...) do {} while (0)
#endif
#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
__FILE__ , ## arg)
#endif

View File

@ -0,0 +1,154 @@
struct hid_class_descriptor {
u8_t bDescriptorType;
u16_t wDescriptorLength;
} __attribute__ ((packed));
struct hid_descriptor {
u8_t bLength;
u8_t bDescriptorType;
u16_t bcdHID;
u8_t bCountryCode;
u8_t bNumDescriptors;
struct hid_class_descriptor desc[1];
} __attribute__ ((packed));
void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d);
Bool init_hid(udev_t *dev)
{
interface_descr_t *interface;
struct hid_descriptor *hds;
struct hid_class_descriptor *hidclass;
u8_t *dptr = (u8_t*)dev->conf;
int i=0, j=0;
dbgprintf( "init hid device\n");
dptr+= dev->conf->bLength;
// for(i = 0; i < dev->conf->bNumInterfaces; i++)
// {
interface = (interface_descr_t*)dptr;
dptr+= interface->bLength;
dbgprintf("interface %d\n\n"
"bLength %d\n"
"bDescriptorType %d\n"
"bInterfaceNumber %d\n"
"bAlternateSetting %d\n"
"bNumEndpoints %d\n"
"bInterfaceClass %d\n"
"bInterfaceSubClass %d\n"
"bInterfaceProtocol %d\n"
"iInterface %d\n\n",
i+1,
interface->bLength,
interface->bDescriptorType,
interface->bInterfaceNumber,
interface->bAlternateSetting,
interface->bNumEndpoints,
interface->bInterfaceClass,
interface->bInterfaceSubClass,
interface->bInterfaceProtocol,
interface->iInterface);
hds = (struct hid_descriptor*) dptr;
dbgprintf("hid descriptor\n\n"
"bLength %d\n"
"bDescriptorType %d\n"
"bcdHID %x\n"
"bCountryCode %d\n"
"bNumDescriptors %d\n",
hds->bLength,
hds->bDescriptorType,
hds->bcdHID,
hds->bCountryCode,
hds->bNumDescriptors);
for(j=0; j < hds->bNumDescriptors; j++)
{
dbgprintf("bDescriptorType %d\n"
"wDescriptorLength %d\n",
hds->desc[j].bDescriptorType,
hds->desc[j].wDescriptorLength);
};
dptr+= hds->bLength;
endpoint_descr_t *ep;
ep = (endpoint_descr_t*)dptr;
dbgprintf("\nendpoint\n\n"
"bLength %d\n"
"bDescriptorType %d\n"
"bEndpointAddress %d\n"
"bmAttributes %d\n"
"wMaxPacketSize %d\n"
"bInterval %d\n",
ep->bLength, ep->bDescriptorType,
ep->bEndpointAddress, ep->bmAttributes,
ep->wMaxPacketSize, ep->bInterval);
dptr+= ep->bLength;
if( interface->bInterfaceProtocol == 2)
create_hid_mouse(dev, ep);
// }
return TRUE;
};
Bool mouse_handler(udev_t *dev, struct tag_request *rq)
{
td_t *td;
td = rq->td_head;
if( (td->status &0x7FF)==rq->size-1)
{
struct boot_packet *pkt;
pkt = (struct boot_packet *)rq->data;
SetMouseData(pkt->buttons, pkt->x, -pkt->y, -pkt->z, 0);
};
td->status = 0x00800000 | dev->speed;
td->token ^= DATA1;
return TRUE;
};
void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d)
{
request_t *rq;
endp_t enp;
addr_t address;
addr_t size;
u32_t toggle;
void *packet;
td_t *td;
qh_t *qh;
static u16_t __attribute__((aligned(16)))
req_set_conf[4] = {0x0900,0x0001,0x0000,0x0000};
if( !ctrl_request(dev, req_set_conf, DOUT, 0, 0))
return;
enp.address = en_d->bEndpointAddress;
enp.size = en_d->wMaxPacketSize;
enp.toggle = DATA0;
packet = malloc(enp.size);
memset(packet, 0, enp.size);
rq = create_request(dev, &enp, DIN, packet, enp.size);
rq->handler = &mouse_handler;
list_prepend(&rq->link, &rq_list);
dbgprintf("create_hid_mouse\n");
}

View File

@ -0,0 +1,42 @@
CC = gcc
FASM = e:/fasm/fasm.exe
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
LDRHD = -shared -T ld.x -s --file-alignment 32
INCLUDES = -I ../include
HFILES:= ../include/types.h \
../include/syscall.h \
../include/link.h \
pci.h \
usb.h
SRC_DEP:= pci.inc \
detect.inc \
hcd.inc \
hid.inc
USB_SRC:= usb.c
USB_OBJ:= usb.obj
USB = usb.dll
all: $(USB)
$(USB): $(USB_OBJ) $(SRC_DEP) $(HFILES) Makefile
wlink name usb.dll SYS nt_dll lib libdrv op offset=0 op nod op maxe=25 op el op STUB=stub.exe op START=_drvEntry @usb.lk1
kpack.exe usb.dll usb.drv
usb.obj : usb.c $(SRC_DEP) $(HFILES) Makefile
$(CC) $(INCLUDES) $(CFLAGS) -o usb.obj usb.c
%.obj : %.c $(HFILES)
$(CC) $(CFLAGS) -o $@ $<
%.obj: %.asm
as -o $@ $<

View File

@ -0,0 +1,95 @@
#pragma pack(push, 1)
typedef struct
{
u16_t device;
u16_t ChipSet;
}PciChipset_t;
#pragma pack(pop)
#define PCI_VENDOR_ID 0x00 /* 16 bits */
#define PCI_DEVICE_ID 0x02 /* 16 bits */
#define PCI_COMMAND 0x04 /* 16 bits */
#define PCI_COMMAND_IO 0x01 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x02 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x04 /* Enable bus mastering */
#define PCI_COMMAND_SPECIAL 0x08 /* Enable response to special cycles */
#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
#define PCI_MAP_REG_START 0x10
#define PCI_MAP_REG_END 0x28
#define PCI_MAP_ROM_REG 0x30
#define PCI_MAP_MEMORY 0x00000000
#define PCI_MAP_IO 0x00000001
#define PCI_MAP_MEMORY_TYPE 0x00000007
#define PCI_MAP_IO_TYPE 0x00000003
#define PCI_MAP_MEMORY_TYPE_32BIT 0x00000000
#define PCI_MAP_MEMORY_TYPE_32BIT_1M 0x00000002
#define PCI_MAP_MEMORY_TYPE_64BIT 0x00000004
#define PCI_MAP_MEMORY_TYPE_MASK 0x00000006
#define PCI_MAP_MEMORY_CACHABLE 0x00000008
#define PCI_MAP_MEMORY_ATTR_MASK 0x0000000e
#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
#define PCI_MAP_IO_ATTR_MASK 0x00000003
#define PCI_MAP_IS_IO(b) ((b) & PCI_MAP_IO)
#define PCI_MAP_IS_MEM(b) (!PCI_MAP_IS_IO(b))
#define PCI_MAP_IS64BITMEM(b) \
(((b) & PCI_MAP_MEMORY_TYPE_MASK) == PCI_MAP_MEMORY_TYPE_64BIT)
#define PCIGETMEMORY(b) ((b) & PCI_MAP_MEMORY_ADDRESS_MASK)
#define PCIGETMEMORY64HIGH(b) (*((CARD32*)&b + 1))
#define PCIGETMEMORY64(b) \
(PCIGETMEMORY(b) | ((CARD64)PCIGETMEMORY64HIGH(b) << 32))
#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
#define PCIGETIO(b) ((b) & PCI_MAP_IO_ADDRESS_MASK)
#define PCI_MAP_ROM_DECODE_ENABLE 0x00000001
#define PCI_MAP_ROM_ADDRESS_MASK 0xfffff800
#define PCIGETROM(b) ((b) & PCI_MAP_ROM_ADDRESS_MASK)
#ifndef PCI_DOM_MASK
# define PCI_DOM_MASK 0x0ffu
#endif
#define PCI_DOMBUS_MASK (((PCI_DOM_MASK) << 8) | 0x0ffu)
#define PCI_MAKE_TAG(b,d,f) ((((b) & (PCI_DOMBUS_MASK)) << 16) | \
(((d) & 0x00001fu) << 11) | \
(((f) & 0x000007u) << 8))
#define PCI_BUS_FROM_TAG(tag) (((tag) >> 16) & (PCI_DOMBUS_MASK))
#define PCI_DEV_FROM_TAG(tag) (((tag) & 0x0000f800u) >> 11)
#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00u) >> 8)
typedef unsigned int PCITAG;
extern inline PCITAG
pciTag(int busnum, int devnum, int funcnum)
{
return(PCI_MAKE_TAG(busnum,devnum,funcnum));
}
u32_t pciGetBaseSize(int bus, int devfn, int index, Bool destructive, Bool *min);
Bool FindPciDevice();

View File

@ -0,0 +1,98 @@
u32_t pciGetBaseSize(int bus, int devfn, int index,
Bool destructive, Bool *min)
{
int offset;
u32_t addr1;
u32_t addr2;
u32_t mask1;
u32_t mask2;
int bits = 0;
/*
* silently ignore bogus index values. Valid values are 0-6. 0-5 are
* the 6 base address registers, and 6 is the ROM base address register.
*/
if (index < 0 || index > 6)
return 0;
if (min)
*min = destructive;
/* Get the PCI offset */
if (index == 6)
offset = PCI_MAP_ROM_REG;
else
offset = PCI_MAP_REG_START + (index << 2);
addr1 = PciRead32(bus, devfn, offset);
/*
* Check if this is the second part of a 64 bit address.
* XXX need to check how endianness affects 64 bit addresses.
*/
if (index > 0 && index < 6) {
addr2 = PciRead32(bus, devfn, offset - 4);
if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
return 0;
}
if (destructive) {
PciWrite32(bus, devfn, offset, 0xffffffff);
mask1 = PciRead32(bus, devfn, offset);
PciWrite32(bus, devfn, offset, addr1);
} else {
mask1 = addr1;
}
/* Check if this is the first part of a 64 bit address. */
if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1))
{
if (PCIGETMEMORY(mask1) == 0)
{
addr2 = PciRead32(bus, devfn, offset + 4);
if (destructive)
{
PciWrite32(bus, devfn, offset + 4, 0xffffffff);
mask2 = PciRead32(bus, devfn, offset + 4);
PciWrite32(bus, devfn, offset + 4, addr2);
}
else
{
mask2 = addr2;
}
if (mask2 == 0)
return 0;
bits = 32;
while ((mask2 & 1) == 0)
{
bits++;
mask2 >>= 1;
}
if (bits > 32)
return bits;
}
}
if (index < 6)
if (PCI_MAP_IS_MEM(mask1))
mask1 = PCIGETMEMORY(mask1);
else
mask1 = PCIGETIO(mask1);
else
mask1 = PCIGETROM(mask1);
if (mask1 == 0)
return 0;
bits = 0;
while ((mask1 & 1) == 0) {
bits++;
mask1 >>= 1;
}
/* I/O maps can be no larger than 8 bits */
if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
bits = 8;
/* ROM maps can be no larger than 24 bits */
if (index == 6 && bits > 24)
bits = 24;
return bits;
}

View File

@ -0,0 +1,27 @@
use32
db 'MENUET01'
dd 1
dd start
dd i_end
dd mem
dd mem
dd 0
dd 0
start:
mov eax, 68
mov ebx, 21
mov ecx, sz_usb
int 0x40
mov eax, -1
int 0x40
sz_usb db '/rd/1/drivers/usb.drv',0
align 4
i_end:
rb 128
mem:

View File

@ -0,0 +1,231 @@
#include "types.h"
#include "link.h"
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include "pci.h"
#include "syscall.h"
#include "usb.h"
int __stdcall srv_usb(ioctl_t *io);
Bool init_hc(hc_t *hc);
static slab_t qh_slab;
static slab_t td_slab;
static link_t hc_list;
static link_t newdev_list;
static link_t rq_list;
u32_t __stdcall drvEntry(int action)
{
u32_t retval;
hc_t *hc;
udev_t *dev;
int i;
if(action != 1)
return 0;
if(!dbg_open("/rd/1/drivers/usb.log"))
{
printf("Can't open /rd/1/drivers/usb.log\nExit\n");
return 0;
}
list_initialize(&hc_list);
list_initialize(&newdev_list);
list_initialize(&rq_list);
if( !FindPciDevice() ) {
dbgprintf("no uhci devices found\n");
return 0;
};
qh_slab.available = 256;
qh_slab.start = KernelAlloc(4096);
qh_slab.nextavail = (addr_t)qh_slab.start;
qh_slab.dma = GetPgAddr(qh_slab.start);
qh_t *p;
addr_t dma;
for (i = 0, p = (qh_t*)qh_slab.start, dma = qh_slab.dma;
i < 256; i++, p++, dma+= sizeof(qh_t))
{
p->qlink = (addr_t)(p+1);
p->qelem = 1;
p->dma = dma;
p->r1 = 0;
};
td_slab.available = 128;
td_slab.start = KernelAlloc(4096);
td_slab.nextavail = (addr_t)td_slab.start;
td_slab.dma = GetPgAddr(td_slab.start);
td_t *td;
for (i = 0, td = (td_t*)td_slab.start, dma = td_slab.dma;
i < 128; i++, td++, dma+= sizeof(td_t))
{
td->link = (addr_t)(td+1);
td->status = 0;
td->token = 0;
td->buffer = 0;
td->dma = dma;
};
hc = (hc_t*)hc_list.next;
while( &hc->link != &hc_list)
{
init_hc(hc);
hc = (hc_t*)hc->link.next;
}
dbgprintf("\n");
dev = (udev_t*)newdev_list.next;
while( &dev->link != &newdev_list)
{
udev_t *tmp = dev;
dev = (udev_t*)dev->link.next;
if(tmp->id != 0)
init_device(tmp);
}
while(1)
{
udev_t *dev;
request_t *rq;
rq = (request_t*)rq_list.next;
while( &rq->link != &rq_list)
{
qh_t *qh;
td_t *td;
td = rq->td_head;
dev = rq->dev;
qh = dev->host->qh1;
qh->qelem = td->dma;
__asm__ __volatile__ ("":::"memory");
rq = (request_t*)rq->link.next;
};
delay(10/10);
rq = (request_t*)rq_list.next;
while( &rq->link != &rq_list)
{
request_t *tmp;
td_t *td;
tmp = rq;
rq = (request_t*)rq->link.next;
td = tmp->td_head;
if( td->status & TD_CTRL_ACTIVE)
continue;
tmp->handler(tmp->dev, tmp);
};
};
retval = RegService("USB", srv_usb);
dbgprintf("reg service USB as: %x\n", retval);
return retval;
};
#define API_VERSION 0x01000100
#define SRV_GETVERSION 0
int __stdcall srv_usb(ioctl_t *io)
{
u32_t *inp;
u32_t *outp;
inp = io->input;
outp = io->output;
switch(io->io_code)
{
case SRV_GETVERSION:
if(io->out_size==4)
{
*outp = API_VERSION;
return 0;
}
break;
default:
return ERR_PARAM;
};
return ERR_PARAM;
}
static qh_t* alloc_qh()
{
if( qh_slab.available )
{
qh_t *qh;
qh_slab.available--;
qh = (qh_t*)qh_slab.nextavail;
qh_slab.nextavail = qh->qlink;
return qh;
}
return NULL;
};
static void free_qh(qh_t *qh)
{
qh->qlink = qh_slab.nextavail;
qh_slab.nextavail = (addr_t)qh;
qh_slab.available++;
};
static td_t* alloc_td()
{
if( td_slab.available )
{
td_t *td;
td_slab.available--;
td = (td_t*)td_slab.nextavail;
td_slab.nextavail = td->link;
return td;
}
return NULL;
};
static void free_td(td_t *td)
{
td->link = td_slab.nextavail;
td_slab.nextavail = (addr_t)td;
td_slab.available++;
};
#include "pci.inc"
#include "detect.inc"
#include "hcd.inc"
#include "hid.inc"

View File

@ -0,0 +1,247 @@
typedef struct {
int available; /**< Count of available items in this slab. */
void *start; /**< Start address of first item. */
addr_t nextavail; /**< The index of next available item. */
addr_t dma;
} slab_t;
#define USB_CLASS_AUDIO 1
#define USB_CLASS_COMM 2
#define USB_CLASS_HID 3
#define USB_CLASS_PHYSICAL 5
#define USB_CLASS_STILL_IMAGE 6
#define USB_CLASS_PRINTER 7
#define USB_CLASS_MASS_STORAGE 8
#define USB_CLASS_HUB 9
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */
#define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPEC 0xfe
#define USB_CLASS_VENDOR_SPEC 0xff
typedef struct
{
addr_t qlink;
addr_t qelem;
addr_t dma;
u32_t r1;
}qh_t __attribute__((aligned(16)));
typedef struct
{
link_t link;
addr_t iobase;
u32_t *frame_base;
count_t frame_number;
addr_t frame_dma;
qh_t *qh1;
u32_t *data;
addr_t data_dma;
u32_t port_map;
int numports;
u32_t pciId;
PCITAG PciTag;
addr_t ioBase[6];
addr_t memBase[6];
size_t memSize[6];
u32_t memType[6];
}hc_t;
typedef struct tag_td
{
/* Hardware fields */
addr_t link;
u32_t status;
u32_t token;
addr_t buffer;
/* Software fields */
addr_t dma;
struct tag_td *bk;
// struct list_head list;
// int frame; /* for iso: what frame? */
// struct list_head fl_list;
u32_t reserved[2];
} td_t __attribute__((aligned(16)));
#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
#define TD_CTRL_C_ERR_SHIFT 27
#define TD_CTRL_LS (1 << 26) /* Low Speed Device */
#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
#define TD_CTRL_NAK (1 << 19) /* NAK Received */
#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
#define TD_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
TD_CTRL_BABBLE | TD_CTRL_CRCTIMEO | \
TD_CTRL_BITSTUFF)
typedef struct __attribute__ ((packed))
{
u8_t bLength;
u8_t bDescriptorType;
u16_t bcdUSB;
u8_t bDeviceClass;
u8_t bDeviceSubClass;
u8_t bDeviceProtocol;
u8_t bMaxPacketSize0;
u16_t idVendor;
u16_t idProduct;
u16_t bcdDevice;
u8_t iManufacturer;
u8_t iProduct;
u8_t iSerialNumber;
u8_t bNumConfigurations;
}dev_descr_t;
typedef struct __attribute__ ((packed))
{
u8_t bLength;
u8_t bDescriptorType;
u16_t wTotalLength;
u8_t bNumInterfaces;
u8_t bConfigurationValue;
u8_t iConfiguration;
u8_t bmAttributes;
u8_t bMaxPower;
}conf_descr_t;
typedef struct __attribute__ ((packed))
{
u8_t bLength;
u8_t bDescriptorType;
u8_t bInterfaceNumber;
u8_t bAlternateSetting;
u8_t bNumEndpoints;
u8_t bInterfaceClass;
u8_t bInterfaceSubClass;
u8_t bInterfaceProtocol;
u8_t iInterface;
}interface_descr_t ;
typedef struct __attribute__ ((packed))
{
u8_t bLength;
u8_t bDescriptorType;
u8_t bEndpointAddress;
u8_t bmAttributes;
u16_t wMaxPacketSize;
u8_t bInterval;
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
u8_t bRefresh;
u8_t bSynchAddress;
}endpoint_descr_t;
typedef struct
{
addr_t address;
addr_t size;
u32_t toggle;
}endp_t;
typedef struct __attribute__ ((packed))
{
u8_t bRequestType;
u8_t bRequest;
u16_t wValue;
u16_t wIndex;
u16_t wLength;
}ctrl_request_t;
typedef struct
{
link_t link;
u32_t id;
hc_t *host;
u32_t speed;
addr_t addr;
addr_t ep0_size;
endp_t enp;
u32_t status;
int port;
dev_descr_t dev_descr;
conf_descr_t *conf;
}udev_t;
typedef struct tag_request
{
link_t link;
td_t *td_head;
td_t *td_tail;
addr_t data;
size_t size;
udev_t *dev;
u32_t type;
Bool (*handler)(udev_t *dev, struct tag_request *rq);
}request_t;
#define DMA(val) GetPgAddr(val)|(((addr_t)(val))&0xFFF)
#define TOKEN( size, toggle, ep, addr, pid) \
( (((size)-1)<<21)|(toggle)|(((ep)&0xF)<<15)|((addr)<<8)|(pid))
Bool ctrl_request(udev_t *dev, void *req, u32_t dir,
void *data, size_t req_size);
Bool set_address(udev_t *dev);
Bool init_device(udev_t *dev);
Bool init_hid(udev_t *dev);
struct boot_packet
{
u8_t buttons;
i8_t x;
i8_t y;
i8_t z;
}__attribute__ ((packed));
#define DOUT 0xE1
#define DIN 0x69
#define DATA0 (0<<19)
#define DATA1 (1<<19)

View File

@ -0,0 +1,22 @@
IMP
_KernelAlloc core.KernelAlloc,
_KernelFree core.KernelFree,
_UserAlloc core.UserAlloc,
_UserFree core.UserFree,
_MapIoMem core.MapIoMem,
_GetPgAddr core.GetPgAddr,
_PciApi core.PciApi,
_PciRead8 core.PciRead8,
_PciRead16 core.PciRead16,
_PciRead32 core.PciRead32,
_PciWrite16 core.PciWrite16,
_PciWrite32 core.PciWrite32,
_RegService core.RegService,
_SysMsgBoardStr core.SysMsgBoardStr,
_Delay core.Delay,
_SetMouseData core.SetMouseData
FIL usb.obj,
vsprintf.obj,
icompute.obj