You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(35) |
Dec
(2) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(37) |
Feb
(10) |
Mar
|
Apr
(2) |
May
(17) |
Jun
(1) |
Jul
(14) |
Aug
(14) |
Sep
(4) |
Oct
|
Nov
(14) |
Dec
(4) |
2005 |
Jan
(6) |
Feb
|
Mar
|
Apr
(6) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
(92) |
Dec
(12) |
2006 |
Jan
(3) |
Feb
(4) |
Mar
|
Apr
(5) |
May
(3) |
Jun
(15) |
Jul
(3) |
Aug
(1) |
Sep
(29) |
Oct
(1) |
Nov
(6) |
Dec
(5) |
2007 |
Jan
(2) |
Feb
(2) |
Mar
|
Apr
(3) |
May
(14) |
Jun
(2) |
Jul
(16) |
Aug
(73) |
Sep
(12) |
Oct
(9) |
Nov
(27) |
Dec
(3) |
2008 |
Jan
(4) |
Feb
(4) |
Mar
(3) |
Apr
(8) |
May
(23) |
Jun
(4) |
Jul
(1) |
Aug
(3) |
Sep
(7) |
Oct
(5) |
Nov
(1) |
Dec
(1) |
2009 |
Jan
|
Feb
(10) |
Mar
|
Apr
(4) |
May
(4) |
Jun
(10) |
Jul
|
Aug
(1) |
Sep
|
Oct
(7) |
Nov
|
Dec
(1) |
2010 |
Jan
|
Feb
(1) |
Mar
|
Apr
(6) |
May
|
Jun
(3) |
Jul
(11) |
Aug
(1) |
Sep
|
Oct
(15) |
Nov
(1) |
Dec
(5) |
2011 |
Jan
(4) |
Feb
(1) |
Mar
(6) |
Apr
|
May
(22) |
Jun
|
Jul
(8) |
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
2012 |
Jan
|
Feb
(10) |
Mar
(1) |
Apr
(6) |
May
(27) |
Jun
(48) |
Jul
(30) |
Aug
(4) |
Sep
|
Oct
(3) |
Nov
(1) |
Dec
(11) |
2013 |
Jan
(4) |
Feb
(7) |
Mar
(6) |
Apr
(18) |
May
(28) |
Jun
(20) |
Jul
|
Aug
(4) |
Sep
(1) |
Oct
(1) |
Nov
(2) |
Dec
(7) |
2014 |
Jan
(3) |
Feb
(2) |
Mar
(4) |
Apr
(9) |
May
(11) |
Jun
(10) |
Jul
|
Aug
(18) |
Sep
(12) |
Oct
(17) |
Nov
(10) |
Dec
(16) |
2015 |
Jan
(5) |
Feb
(1) |
Mar
(5) |
Apr
(4) |
May
(28) |
Jun
(2) |
Jul
|
Aug
|
Sep
(6) |
Oct
|
Nov
(2) |
Dec
(1) |
2016 |
Jan
(14) |
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
(3) |
Jul
(4) |
Aug
(4) |
Sep
(1) |
Oct
(1) |
Nov
|
Dec
(1) |
2017 |
Jan
(11) |
Feb
|
Mar
(21) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2018 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
(2) |
Sep
(4) |
Oct
(4) |
Nov
|
Dec
(1) |
2019 |
Jan
(1) |
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(13) |
Sep
(4) |
Oct
|
Nov
|
Dec
|
2020 |
Jan
(10) |
Feb
(9) |
Mar
(5) |
Apr
(4) |
May
(3) |
Jun
(18) |
Jul
(4) |
Aug
(2) |
Sep
(20) |
Oct
(2) |
Nov
|
Dec
|
2021 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(1) |
Jun
(2) |
Jul
(1) |
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
2022 |
Jan
(1) |
Feb
(2) |
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(5) |
Sep
|
Oct
(1) |
Nov
|
Dec
(1) |
2023 |
Jan
(10) |
Feb
(7) |
Mar
(29) |
Apr
(31) |
May
(29) |
Jun
(34) |
Jul
(3) |
Aug
(24) |
Sep
(22) |
Oct
(10) |
Nov
(38) |
Dec
(27) |
2024 |
Jan
(15) |
Feb
(8) |
Mar
(4) |
Apr
(20) |
May
(33) |
Jun
(18) |
Jul
(15) |
Aug
(23) |
Sep
(26) |
Oct
(32) |
Nov
(6) |
Dec
(4) |
2025 |
Jan
(7) |
Feb
(1) |
Mar
(1) |
Apr
(4) |
May
(46) |
Jun
(19) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <ljs...@us...> - 2011-05-09 01:30:16
|
Revision: 717 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=717&view=rev Author: ljsebald Date: 2011-05-09 01:30:10 +0000 (Mon, 09 May 2011) Log Message: ----------- Fix a bug if you were to try to open the same list that is already open in the PVR code. Modified Paths: -------------- kos/kernel/arch/dreamcast/hardware/pvr/pvr_scene.c Modified: kos/kernel/arch/dreamcast/hardware/pvr/pvr_scene.c =================================================================== --- kos/kernel/arch/dreamcast/hardware/pvr/pvr_scene.c 2011-05-08 02:39:43 UTC (rev 716) +++ kos/kernel/arch/dreamcast/hardware/pvr/pvr_scene.c 2011-05-09 01:30:10 UTC (rev 717) @@ -144,7 +144,7 @@ #endif /* !NDEBUG */ /* If we already had a list open, close it first */ - if (pvr_state.list_reg_open != -1) + if (pvr_state.list_reg_open != -1 && pvr_state.list_reg_open != list) pvr_list_finish(); /* Ok, set the flag */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-05-08 02:39:50
|
Revision: 716 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=716&view=rev Author: ljsebald Date: 2011-05-08 02:39:43 +0000 (Sun, 08 May 2011) Log Message: ----------- 2002 called. They wanted to ask why this stuff was still around today. Finally its time to kill off the old Maple API... Modified Paths: -------------- kos/kernel/arch/dreamcast/hardware/maple/Makefile kos/kernel/arch/dreamcast/include/dc/maple/controller.h kos/kernel/arch/dreamcast/include/dc/maple/mouse.h kos/kernel/arch/dreamcast/include/dc/maple.h Removed Paths: ------------- kos/kernel/arch/dreamcast/hardware/maple/maple_compat.c Modified: kos/kernel/arch/dreamcast/hardware/maple/Makefile =================================================================== --- kos/kernel/arch/dreamcast/hardware/maple/Makefile 2011-05-07 19:57:04 UTC (rev 715) +++ kos/kernel/arch/dreamcast/hardware/maple/Makefile 2011-05-08 02:39:43 UTC (rev 716) @@ -16,9 +16,6 @@ # Output devices OBJS := $(OBJS) vmu.o -# Old maple compatibility -OBJS := $(OBJS) maple_compat.o - SUBDIRS = include $(KOS_BASE)/Makefile.prefab Deleted: kos/kernel/arch/dreamcast/hardware/maple/maple_compat.c =================================================================== --- kos/kernel/arch/dreamcast/hardware/maple/maple_compat.c 2011-05-07 19:57:04 UTC (rev 715) +++ kos/kernel/arch/dreamcast/hardware/maple/maple_compat.c 2011-05-08 02:39:43 UTC (rev 716) @@ -1,138 +0,0 @@ -/* KallistiOS ##version## - - maple_compat.c - (C)2002 Dan Potter - - */ - -#include <assert.h> -#include <string.h> -#include <dc/maple.h> -#include <dc/maple/controller.h> -#include <dc/maple/mouse.h> - -/* Utility function used by other compat functions */ -int maple_compat_resolve(uint8 addr, maple_device_t **dev, uint32 funcs) { - int p, u; - - maple_raddr(addr, &p, &u); - if (!maple_dev_valid(p, u)) - return MAPLE_EINVALID; - *dev = &maple_state.ports[p].units[u]; - if (! ((*dev)->info.functions & funcs) ) - return MAPLE_ENOTSUPP; - - return 0; -} - -/****************************************************************************/ -/* maple.c */ - -/* Retrieve function code... */ -uint32 maple_device_func(int p, int u) { - maple_device_t *dev; - dev = &maple_state.ports[p].units[u]; - if (!dev->valid) - return 0; - else - return dev->info.functions; -} - -/* First with a given function code... */ -uint8 maple_first_device(int code) { - int p, u; - uint32 func; - - for (p=0; p<MAPLE_PORT_COUNT; p++) - for (u=0; u<MAPLE_UNIT_COUNT; u++) { - func = maple_device_func(p, u); - if (func & code) - return maple_addr(p, u); - } - return 0; -} - -/* First controller */ -uint8 maple_first_controller() { - return maple_first_device(MAPLE_FUNC_CONTROLLER); -} - -/* First mouse */ -uint8 maple_first_mouse() { - return maple_first_device(MAPLE_FUNC_MOUSE); -} - -/* First keyboard */ -uint8 maple_first_kb() { - return maple_first_device(MAPLE_FUNC_KEYBOARD); -} - -/* First LCD unit */ -uint8 maple_first_lcd() { - return maple_first_device(MAPLE_FUNC_LCD); -} - -/* First VMU */ -uint8 maple_first_vmu() { - return maple_first_device(MAPLE_FUNC_MEMCARD); -} - -/****************************************************************************/ -/* controller.c */ - -/* Get the old compatible condition structure for controller on port - and fill in cond with it, ret -1 on error. */ -int cont_get_cond(uint8 addr, cont_cond_t *cond) { - int rv; - maple_device_t *dev; - cont_state_t *stat; - - /* Resolve a status struct */ - assert( addr != 0 ); - rv = maple_compat_resolve(addr, &dev, MAPLE_FUNC_CONTROLLER); - if (rv < 0) - return rv; - - stat = maple_dev_status(dev); - assert(stat != NULL); - - /* Copy out the pieces into an old compat struct */ - cond->buttons = (uint16)(~stat->buttons); - cond->ltrig = (uint8)(stat->ltrig); - cond->rtrig = (uint8)(stat->rtrig); - cond->joyx = (uint8)(stat->joyx+128); - cond->joyy = (uint8)(stat->joyy+128); - cond->joy2x = (uint8)(stat->joy2x+128); - cond->joy2y = (uint8)(stat->joy2y+128); - - return 0; -} - -/****************************************************************************/ -/* mouse.c */ - -/* get the condition structure for a mouse at address addr. return a - -1 if an error occurs. */ -int mouse_get_cond(uint8 addr, mouse_cond_t *cond) { - int rv; - maple_device_t *dev; - mouse_state_t *stat; - - assert( addr != 0 ); - rv = maple_compat_resolve(addr, &dev, MAPLE_FUNC_MOUSE); - if (rv < 0) - return rv; - - stat = maple_dev_status(dev); - assert(stat != NULL); - - /* Copy out the pieces into an old compat struct */ - cond->buttons = (uint16)(~stat->buttons); - cond->dummy1 = cond->dummy2 = cond->dummy3 = cond->dummy4 = 0; - cond->dx = stat->dx; - cond->dy = stat->dy; - cond->dz = stat->dz; - - return 0; -} - Modified: kos/kernel/arch/dreamcast/include/dc/maple/controller.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/maple/controller.h 2011-05-07 19:57:04 UTC (rev 715) +++ kos/kernel/arch/dreamcast/include/dc/maple/controller.h 2011-05-08 02:39:43 UTC (rev 716) @@ -115,9 +115,6 @@ void cont_shutdown(); /* \endcond */ -/* Compat function */ -int cont_get_cond(uint8 addr, cont_cond_t *cond) __attribute__((deprecated)); - /** \brief Controller automatic callback type. Functions of this type can be set with cont_btn_callback() to respond Modified: kos/kernel/arch/dreamcast/include/dc/maple/mouse.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/maple/mouse.h 2011-05-07 19:57:04 UTC (rev 715) +++ kos/kernel/arch/dreamcast/include/dc/maple/mouse.h 2011-05-08 02:39:43 UTC (rev 716) @@ -82,9 +82,6 @@ int dz; } mouse_state_t; -/* Old maple interface */ -int mouse_get_cond(uint8 addr, mouse_cond_t *cond) __attribute__((deprecated)); - /* \cond */ /* Init / Shutdown */ int mouse_init(); Modified: kos/kernel/arch/dreamcast/include/dc/maple.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/maple.h 2011-05-07 19:57:04 UTC (rev 715) +++ kos/kernel/arch/dreamcast/include/dc/maple.h 2011-05-08 02:39:43 UTC (rev 716) @@ -352,39 +352,6 @@ void * maple_dev_status(maple_device_t *dev); /**************************************************************************/ -/* maple_compat.h */ - -/* Utility function used by other compat functions */ -int maple_compat_resolve(uint8 addr, maple_device_t **dev, uint32 funcs); - -/* Retrieve function code... */ -uint32 maple_device_func(int port, int unit) __attribute__((deprecated)); - -/* First with a given function code... */ -uint8 maple_first_device(int code) __attribute__((deprecated)); - -/* First controller */ -uint8 maple_first_controller() __attribute__((deprecated)); - -/* First mouse */ -uint8 maple_first_mouse() __attribute__((deprecated)); - -/* First keyboard */ -uint8 maple_first_kb() __attribute__((deprecated)); - -/* First LCD unit */ -uint8 maple_first_lcd() __attribute__((deprecated)); - -/* First VMU */ -uint8 maple_first_vmu() __attribute__((deprecated)); - -/* NOP now */ -#define maple_rescan_bus(Q) /* NADA */ - -/* Renamed */ -#define maple_create_addr(A, B) maple_addr(A, B) - -/**************************************************************************/ /* maple_init.c */ /* Init / Shutdown */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-05-07 19:57:10
|
Revision: 715 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=715&view=rev Author: ljsebald Date: 2011-05-07 19:57:04 +0000 (Sat, 07 May 2011) Log Message: ----------- Committing the first big batch of documentation on pvr.h... This is not at all finished, but its a good start... Modified Paths: -------------- kos/kernel/arch/dreamcast/include/dc/pvr.h Modified: kos/kernel/arch/dreamcast/include/dc/pvr.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/pvr.h 2011-05-07 19:54:54 UTC (rev 714) +++ kos/kernel/arch/dreamcast/include/dc/pvr.h 2011-05-07 19:57:04 UTC (rev 715) @@ -1,14 +1,32 @@ /* KallistiOS ##version## - kernel/arch/dreamcast/include/dc/pvr.h - (C)2002 Dan Potter + dc/pvr.h + Copyright (C) 2002 Dan Potter Low-level PVR 3D interface for the DC Note: this API does _not_ handle any sort of transformations (including perspective!) so for that, you should look to KGL. */ +/** \file dc/pvr.h + \brief Low-level PVR (3D hardware) interface. + This file provides support for using the PVR 3D hardware in the Dreamcast. + Note that this does not handle any sort of perspective transformations or + anything of the like. This is just a very thin wrapper around the actual + hardware support. + + This file is used for pretty much everything related to the PVR, from memory + management to actual primitive rendering. + + \author Dan Potter + \author Roger Cattermole + \author Paul Boese + \author Brian Paul + \author Lawrence Sebald + \author Benoit Miller +*/ + #ifndef __DC_PVR_H #define __DC_PVR_H @@ -21,194 +39,393 @@ /* Data types ********************************************************/ -/* PVR texture memory pointer; unlike the old "TA" system, PVR pointers - in the new system are actually SH-4 compatible pointers and can - be used directly in place of ta_txr_map(). */ +/** \brief PVR texture memory pointer. + + Unlike the old "TA" system, PVR pointers in the new system are actually SH-4 + compatible pointers and can be used directly in place of ta_txr_map(). + + Not that anyone probably even remembers the old TA system anymore... */ typedef void * pvr_ptr_t; -/* PVR list specification */ +/** \brief PVR list specification. + + Each primitive in the PVR is submitted to one of the hardware primitive + lists. This type is an identifier for a list. + + \see pvr_lists +*/ typedef uint32 pvr_list_t; -/* Polygon context; you should use this more human readable format for - specifying your polygon contexts, and then compile them into polygon - headers (below) when you are ready to start using them. +/** \brief PVR polygon context. - This has embedded structures in it for two reasons; the first reason - is to make it easier for me to add new stuff later without breaking - existing code. The second reason is to make it more readable and - usable. -*/ + You should use this more human readable format for specifying your polygon + contexts, and then compile them into polygon headers when you are ready to + start using them. + + This has embedded structures in it for two reasons; the first reason is to + make it easier for me to add new stuff later without breaking existing code. + The second reason is to make it more readable and usable. + + Unfortunately, it seems that Doxygen chokes up a little bit on this + structure, and others like it. The documentation should still be mostly + understandable though... + + \headerfile dc/pvr.h +*/ typedef struct { - int list_type; - struct { - int alpha; - int shading; - int fog_type; - int culling; - int color_clamp; - int clip_mode; - int modifier_mode; - int alpha2; - int fog_type2; - int color_clamp2; - } gen; - struct { - int src, dst; - int src_enable, dst_enable; - int src2, dst2; - int src_enable2, dst_enable2; - } blend; - struct { - int color; - int uv; - int modifier; - } fmt; - struct { - int comparison; - int write; - } depth; - struct { - int enable; - int filter; /* none, bi-linear, tri-linear, etc */ - int mipmap; - int mipmap_bias; - int uv_flip; - int uv_clamp; - int alpha; - int env; - int width; - int height; - int format; /* bit format, vq, twiddle, stride */ - pvr_ptr_t base; /* texture location */ - } txr; + int list_type; /**< \brief Primitive list + \see pvr_lists */ struct { - int enable; - int filter; /* none, bi-linear, tri-linear, etc */ - int mipmap; - int mipmap_bias; - int uv_flip; - int uv_clamp; - int alpha; - int env; - int width; - int height; - int format; /* bit format, vq, twiddle, stride */ - pvr_ptr_t base; /* texture location */ - } txr2; + int alpha; /**< \brief Enable or disable alpha outside modifier + \see pvr_alpha_switch */ + int shading; /**< \brief Shading type + \see pvr_shading_types */ + int fog_type; /**< \brief Fog type outside modifier + \see pvr_fog_types */ + int culling; /**< \brief Culling mode + \see pvr_cull_modes */ + int color_clamp; /**< \brief Color clamp enable/disable outside modifier + \see pvr_colclamp_switch */ + int clip_mode; /**< \brief Clipping mode + \see pvr_clip_modes */ + int modifier_mode; /**< \brief Modifier mode */ + int alpha2; /**< \brief Enable/disable alpha inside modifier + \see pvr_alpha_switch */ + int fog_type2; /**< \brief Fog type inside modifier + \see pvr_fog_types */ + int color_clamp2; /**< \brief Color clamp enable/disable inside modifier + \see pvr_colclamp_switch */ + } gen; /**< \brief General parameters */ + struct { + int src; /**< \brief Source blending mode outside modifier + \see pvr_blend_modes */ + int dst; /**< \brief Dest blending mode outside modifier + \see pvr_blend_modes */ + int src_enable; /**< \brief Source blending enable outside modifier + \see pvr_blend_switch */ + int dst_enable; /**< \brief Dest blending enable outside modifier + \see pvr_blend_switch */ + int src2; /**< \brief Source blending mode inside modifier + \see pvr_blend_modes */ + int dst2; /**< \brief Dest blending mode inside modifier + \see pvr_blend_modes */ + int src_enable2; /**< \brief Source blending mode inside modifier + \see pvr_blend_switch */ + int dst_enable2; /**< \brief Dest blending mode inside modifier + \see pvr_blend_switch */ + } blend; /**< \brief Blending parameters */ + struct { + int color; /**< \brief Color format in vertex + \see pvr_color_fmts */ + int uv; /**< \brief U/V data format in vertex + \see pvr_uv_fmts */ + int modifier; /**< \brief Enable or disable modifier effect + \see pvr_mod_switch */ + } fmt; /**< \brief Format control */ + struct { + int comparison; /**< \brief Depth comparison mode + \see pvr_depth_modes */ + int write; /**< \brief Enable or disable depth writes + \see pvr_depth_switch */ + } depth; /**< \brief Depth comparison/write modes */ + struct { + int enable; /**< \brief Enable/disable texturing + \see pvr_txr_switch */ + int filter; /**< \brief Filtering mode + \see pvr_filter_modes */ + int mipmap; /**< \brief Enable/disable mipmaps + \see pvr_mip_switch */ + int mipmap_bias; /**< \brief Mipmap bias + \see pvr_mip_bias */ + int uv_flip; /**< \brief Enable/disable U/V flipping + \see pvr_uv_flip */ + int uv_clamp; /**< \brief Enable/disable U/V clamping + \see pvr_uv_clamp */ + int alpha; /**< \brief Enable/disable texture alpha + \see pvr_txralpha_switch */ + int env; /**< \brief Texture color contribution + \see pvr_txrenv_modes */ + int width; /**< \brief Texture width (requires a power of 2) */ + int height; /**< \brief Texture height (requires a power of 2) */ + int format; /**< \brief Texture format + \see pvr_txr_fmts */ + pvr_ptr_t base; /**< \brief Texture pointer */ + } txr; /**< \brief Texturing params outside modifier */ + struct { + int enable; /**< \brief Enable/disable texturing + \see pvr_txr_switch */ + int filter; /**< \brief Filtering mode + \see pvr_filter_modes */ + int mipmap; /**< \brief Enable/disable mipmaps + \see pvr_mip_switch */ + int mipmap_bias; /**< \brief Mipmap bias + \see pvr_mip_bias */ + int uv_flip; /**< \brief Enable/disable U/V flipping + \see pvr_uv_flip */ + int uv_clamp; /**< \brief Enable/disable U/V clamping + \see pvr_uv_clamp */ + int alpha; /**< \brief Enable/disable texture alpha + \see pvr_txralpha_switch */ + int env; /**< \brief Texture color contribution + \see pvr_txrenv_modes */ + int width; /**< \brief Texture width (requires a power of 2) */ + int height; /**< \brief Texture height (requires a power of 2) */ + int format; /**< \brief Texture format + \see pvr_txr_fmts */ + pvr_ptr_t base; /**< \brief Texture pointer */ + } txr2; /**< \brief Texturing params inside modifier */ } pvr_poly_cxt_t; -/* Sprite context; use this somewhat readable format to specify your - sprites before compiling them into polygon headers. +/** \brief PVR sprite context. + + You should use this more human readable format for specifying your sprite + contexts, and then compile them into sprite headers when you are ready to + start using them. + + Unfortunately, it seems that Doxygen chokes up a little bit on this + structure, and others like it. The documentation should still be mostly + understandable though... + + \headerfile dc/pvr.h */ typedef struct { - int list_type; - struct { - int alpha; - int fog_type; - int culling; - int color_clamp; - int clip_mode; - } gen; - struct { - int src, dst; - int src_enable, dst_enable; + int list_type; /**< \brief Primitive list + \see pvr_lists */ + struct { + int alpha; /**< \brief Enable or disable alpha outside modifier + \see pvr_alpha_switch */ + int fog_type; /**< \brief Fog type outside modifier + \see pvr_fog_types */ + int culling; /**< \brief Culling mode + \see pvr_cull_modes */ + int color_clamp; /**< \brief Color clamp enable/disable outside modifier + \see pvr_colclamp_switch */ + int clip_mode; /**< \brief Clipping mode + \see pvr_clip_modes */ + } gen; /**< \brief General parameters */ + struct { + int src; /**< \brief Source blending mode outside modifier + \see pvr_blend_modes */ + int dst; /**< \brief Dest blending mode outside modifier + \see pvr_blend_modes */ + int src_enable; /**< \brief Source blending enable outside modifier + \see pvr_blend_switch */ + int dst_enable; /**< \brief Dest blending enable outside modifier + \see pvr_blend_switch */ } blend; - struct { - int comparison; - int write; - } depth; - struct { - int enable; - int filter; - int mipmap; - int mipmap_bias; - int uv_flip; - int uv_clamp; - int alpha; - int width; - int height; - int format; - pvr_ptr_t base; - } txr; + struct { + int comparison; /**< \brief Depth comparison mode + \see pvr_depth_modes */ + int write; /**< \brief Enable or disable depth writes + \see pvr_depth_switch */ + } depth; /**< \brief Depth comparison/write modes */ + struct { + int enable; /**< \brief Enable/disable texturing + \see pvr_txr_switch */ + int filter; /**< \brief Filtering mode + \see pvr_filter_modes */ + int mipmap; /**< \brief Enable/disable mipmaps + \see pvr_mip_switch */ + int mipmap_bias; /**< \brief Mipmap bias + \see pvr_mip_bias */ + int uv_flip; /**< \brief Enable/disable U/V flipping + \see pvr_uv_flip */ + int uv_clamp; /**< \brief Enable/disable U/V clamping + \see pvr_uv_clamp */ + int alpha; /**< \brief Enable/disable texture alpha + \see pvr_txralpha_switch */ + int width; /**< \brief Texture width (requires a power of 2) */ + int height; /**< \brief Texture height (requires a power of 2) */ + int format; /**< \brief Texture format + \see pvr_txr_fmts */ + pvr_ptr_t base; /**< \brief Texture pointer */ + } txr; /**< \brief Texturing params */ } pvr_sprite_cxt_t; /* Constants for the above structure; thanks to Benoit Miller for these */ -/* list_type */ -#define PVR_LIST_OP_POLY 0 /* opaque poly */ -#define PVR_LIST_OP_MOD 1 /* opaque modifier */ -#define PVR_LIST_TR_POLY 2 /* translucent poly */ -#define PVR_LIST_TR_MOD 3 /* translucent modifier */ -#define PVR_LIST_PT_POLY 4 /* punch-thru poly */ -#define PVR_SHADE_FLAT 0 /* shading */ -#define PVR_SHADE_GOURAUD 1 +/** \defgroup pvr_lists PVR primitive list types -#define PVR_DEPTHCMP_NEVER 0 /* depth_comparison */ -#define PVR_DEPTHCMP_LESS 1 -#define PVR_DEPTHCMP_EQUAL 2 -#define PVR_DEPTHCMP_LEQUAL 3 -#define PVR_DEPTHCMP_GREATER 4 -#define PVR_DEPTHCMP_NOTEQUAL 5 -#define PVR_DEPTHCMP_GEQUAL 6 -#define PVR_DEPTHCMP_ALWAYS 7 + Each primitive submitted to the PVR must be placed in one of these lists, + depending on its characteristics. -#define PVR_CULLING_NONE 0 /* culling */ -#define PVR_CULLING_SMALL 1 -#define PVR_CULLING_CCW 2 -#define PVR_CULLING_CW 3 + @{ +*/ +#define PVR_LIST_OP_POLY 0 /**< \brief Opaque polygon list */ +#define PVR_LIST_OP_MOD 1 /**< \brief Opaque modifier list */ +#define PVR_LIST_TR_POLY 2 /**< \brief Translucent polygon list */ +#define PVR_LIST_TR_MOD 3 /**< \brief Translucent modifier list*/ +#define PVR_LIST_PT_POLY 4 /**< \brief Punch-thru polygon list */ +/** @} */ -#define PVR_DEPTHWRITE_ENABLE 0 /* depth_write */ -#define PVR_DEPTHWRITE_DISABLE 1 +/** \defgroup pvr_shading_types PVR shading modes -#define PVR_TEXTURE_DISABLE 0 /* txr_enable */ -#define PVR_TEXTURE_ENABLE 1 + Each polygon can define how it wants to be shaded, be it with flat or + Gouraud shading using these constants in the appropriate place in its + pvr_poly_cxt_t. -#define PVR_BLEND_ZERO 0 /* src_blend / dst_blend */ -#define PVR_BLEND_ONE 1 -#define PVR_BLEND_DESTCOLOR 2 -#define PVR_BLEND_INVDESTCOLOR 3 -#define PVR_BLEND_SRCALPHA 4 -#define PVR_BLEND_INVSRCALPHA 5 -#define PVR_BLEND_DESTALPHA 6 -#define PVR_BLEND_INVDESTALPHA 7 + @{ +*/ +#define PVR_SHADE_FLAT 0 /**< \brief Use flat shading */ +#define PVR_SHADE_GOURAUD 1 /**< \brief Use Gouraud shading */ +/** @} */ -#define PVR_BLEND_DISABLE 0 /* src_blend_enable / dst_blend_enable */ -#define PVR_BLEND_ENABLE 1 +/** \defgroup pvr_depth_modes PVR depth comparison modes -#define PVR_FOG_TABLE 0 /* fog_type */ -#define PVR_FOG_VERTEX 1 -#define PVR_FOG_DISABLE 2 -#define PVR_FOG_TABLE2 3 + These set the depth function used for comparisons. -#define PVR_USERCLIP_DISABLE 0 /* clip_mode */ -#define PVR_USERCLIP_INSIDE 2 -#define PVR_USERCLIP_OUTSIDE 3 + @{ +*/ +#define PVR_DEPTHCMP_NEVER 0 /**< \brief Never pass */ +#define PVR_DEPTHCMP_LESS 1 /**< \brief Less than */ +#define PVR_DEPTHCMP_EQUAL 2 /**< \brief Equal to */ +#define PVR_DEPTHCMP_LEQUAL 3 /**< \brief Less than or equal to */ +#define PVR_DEPTHCMP_GREATER 4 /**< \brief Greater than */ +#define PVR_DEPTHCMP_NOTEQUAL 5 /**< \brief Not equal to */ +#define PVR_DEPTHCMP_GEQUAL 6 /**< \brief Greater than or equal to */ +#define PVR_DEPTHCMP_ALWAYS 7 /**< \brief Always pass */ +/** @} */ -#define PVR_CLRCLAMP_DISABLE 0 /* color_clamp */ -#define PVR_CLRCLAMP_ENABLE 1 +/** \defgroup pvr_cull_modes PVR culling modes -#define PVR_ALPHA_DISABLE 0 /* alpha */ -#define PVR_ALPHA_ENABLE 1 + These culling modes can be set by polygons to determine when they are + culled. They work pretty much as you'd expect them to if you've ever used + any 3D hardware before. -#define PVR_TXRALPHA_ENABLE 0 /* txr_alpha */ -#define PVR_TXRALPHA_DISABLE 1 + @{ +*/ +#define PVR_CULLING_NONE 0 /**< \brief Disable culling */ +#define PVR_CULLING_SMALL 1 /**< \brief Cull if small */ +#define PVR_CULLING_CCW 2 /**< \brief Cull if counterclockwise */ +#define PVR_CULLING_CW 3 /**< \brief Cull if clockwise */ +/** @} */ -#define PVR_UVFLIP_NONE 0 /* txr_uvflip */ -#define PVR_UVFLIP_V 1 -#define PVR_UVFLIP_U 2 -#define PVR_UVFLIP_UV 3 +/** \defgroup pvr_depth_switch Enable or disable PVR depth writes + @{ +*/ +#define PVR_DEPTHWRITE_ENABLE 0 /**< \brief Update the Z value */ +#define PVR_DEPTHWRITE_DISABLE 1 /**< \brief Do not update the Z value */ +/** @} */ -#define PVR_UVCLAMP_NONE 0 /* txr_uvclamp */ -#define PVR_UVCLAMP_V 1 -#define PVR_UVCLAMP_U 2 -#define PVR_UVCLAMP_UV 3 +/** \defgroup pvr_txr_switch Enable or disable texturing on polygons + @{ +*/ +#define PVR_TEXTURE_DISABLE 0 /**< \brief Disable texturing */ +#define PVR_TEXTURE_ENABLE 1 /**< \brief Enable texturing */ +/** @} */ -#define PVR_FILTER_NONE 0 /* txr_filter */ -#define PVR_FILTER_NEAREST 0 -#define PVR_FILTER_BILINEAR 2 -#define PVR_FILTER_TRILINEAR1 4 -#define PVR_FILTER_TRILINEAR2 6 +/** \defgroup pvr_blend_modes PVR blending modes + These are all the blending modes that can be done with regard to alpha + blending on the PVR. + + @{ +*/ +#define PVR_BLEND_ZERO 0 /**< \brief None of this color */ +#define PVR_BLEND_ONE 1 /**< \brief All of this color */ +#define PVR_BLEND_DESTCOLOR 2 /**< \brief Destination color */ +#define PVR_BLEND_INVDESTCOLOR 3 /**< \brief Inverse of destination color */ +#define PVR_BLEND_SRCALPHA 4 /**< \brief Blend with source alpha */ +#define PVR_BLEND_INVSRCALPHA 5 /**< \brief Blend with inverse source alpha */ +#define PVR_BLEND_DESTALPHA 6 /**< \brief Blend with destination alpha */ +#define PVR_BLEND_INVDESTALPHA 7 /**< \brief Blend with inverse destination alpha */ +/** @} */ + +/** \defgroup pvr_blend_switch Enable or disable blending + @{ +*/ +#define PVR_BLEND_DISABLE 0 /**< \brief Disable blending */ +#define PVR_BLEND_ENABLE 1 /**< \brief Enable blending */ +/** @} */ + +/** \defgroup pvr_fog_types PVR fog modes + + Each polygon can decide what fog type is used with regard to it using these + constants in its pvr_poly_cxt_t. + + @{ +*/ +#define PVR_FOG_TABLE 0 /**< \brief Table fog */ +#define PVR_FOG_VERTEX 1 /**< \brief Vertex fog */ +#define PVR_FOG_DISABLE 2 /**< \brief Disable fog */ +#define PVR_FOG_TABLE2 3 /**< \brief Table fog mode 2 */ +/** @} */ + +/** \defgroup pvr_clip_modes PVR clipping modes + + These control how primitives are clipped against the user clipping area. + + @{ +*/ +#define PVR_USERCLIP_DISABLE 0 /**< \brief Disable clipping */ +#define PVR_USERCLIP_INSIDE 2 /**< \brief Enable clipping inside area */ +#define PVR_USERCLIP_OUTSIDE 3 /**< \brief Enable clipping outside area */ +/** @} */ + +/** \defgroup pvr_colclamp_switch Enable or disable color clamping + + Enabling color clamping will clamp colors between the minimum and maximum + values before any sort of fog processing. + + @{ +*/ +#define PVR_CLRCLAMP_DISABLE 0 /**< \brief Disable color clamping */ +#define PVR_CLRCLAMP_ENABLE 1 /**< \brief Enable color clamping */ +/** @} */ + +/** \defgroup pvr_alpha_switch Enable or disable alpha blending + + This causes the alpha value in the vertex color to be paid attention to. It + really only makes sense to enable this for translucent or punch-thru polys. + + @{ +*/ +#define PVR_ALPHA_DISABLE 0 /**< \brief Disable alpha blending */ +#define PVR_ALPHA_ENABLE 1 /**< \brief Enable alpha blending */ +/** @} */ + +/** \defgroup pvr_txralpha_switch Enable or disable texture alpha blending + + This causes the alpha value in the texel color to be paid attention to. It + really only makes sense to enable this for translucent or punch-thru polys. + + @{ +*/ +#define PVR_TXRALPHA_ENABLE 0 /**< \brief Enable alpha blending */ +#define PVR_TXRALPHA_DISABLE 1 /**< \brief Disable alpha blending */ +/** @} */ + +/** \defgroup pvr_uv_flip Enable or disable U/V flipping on the PVR + @{ +*/ +#define PVR_UVFLIP_NONE 0 /**< \brief No flipped coordinates */ +#define PVR_UVFLIP_V 1 /**< \brief Flip V only */ +#define PVR_UVFLIP_U 2 /**< \brief Flip U only */ +#define PVR_UVFLIP_UV 3 /**< \brief Flip U and V */ +/** @} */ + +/** \defgroup pvr_uv_clamp Enable or disable clamping of U/V on the PVR + @{ +*/ +#define PVR_UVCLAMP_NONE 0 /**< \brief Disable clamping */ +#define PVR_UVCLAMP_V 1 /**< \brief Clamp V only */ +#define PVR_UVCLAMP_U 2 /**< \brief Clamp U only */ +#define PVR_UVCLAMP_UV 3 /**< \brief Clamp U and V */ +/** @} */ + +/** \defgroup pvr_filter_modes PVR texture sampling modes + @{ +*/ +#define PVR_FILTER_NONE 0 /**< \brief No filtering (point sample) */ +#define PVR_FILTER_NEAREST 0 /**< \brief No filtering (point sample) */ +#define PVR_FILTER_BILINEAR 2 /**< \brief Bilinear interpolation */ +#define PVR_FILTER_TRILINEAR1 4 /**< \brief Trilinear interpolation pass 1 */ +#define PVR_FILTER_TRILINEAR2 6 /**< \brief Trilinear interpolation pass 2 */ +/** @} */ + +/** \defgroup pvr_mip_bias PVR mipmap bias modes + @{ +*/ #define PVR_MIPBIAS_NORMAL PVR_MIPBIAS_1_00 /* txr_mipmap_bias */ #define PVR_MIPBIAS_0_25 1 #define PVR_MIPBIAS_0_50 2 @@ -225,48 +442,84 @@ #define PVR_MIPBIAS_3_25 13 #define PVR_MIPBIAS_3_50 14 #define PVR_MIPBIAS_3_75 15 +/** @} */ -/* txr_env */ -#define PVR_TXRENV_REPLACE 0 /* C = Ct, A = At */ -#define PVR_TXRENV_MODULATE 1 /* C = Cs * Ct, A = At */ -#define PVR_TXRENV_DECAL 2 /* C = (Cs * At) + (Cs * (1-At)), A = As */ -#define PVR_TXRENV_MODULATEALPHA 3 /* C = Cs * Ct, A = As * At */ +/** \defgroup pvr_txrenv_modes Texture color calculation modes + @{ +*/ +#define PVR_TXRENV_REPLACE 0 /**< \brief C = Ct, A = At */ +#define PVR_TXRENV_MODULATE 1 /**< \brief C = Cs * Ct, A = At */ +#define PVR_TXRENV_DECAL 2 /**< \brief C = (Cs * At) + (Cs * (1-At)), A = As */ +#define PVR_TXRENV_MODULATEALPHA 3 /**< \brief C = Cs * Ct, A = As * At */ +/** @} */ -#define PVR_MIPMAP_DISABLE 0 /* txr_mipmap */ -#define PVR_MIPMAP_ENABLE 1 +/** \defgroup pvr_mip_switch Enable or disable PVR mipmap processing + @{ +*/ +#define PVR_MIPMAP_DISABLE 0 /**< \brief Disable mipmap processing */ +#define PVR_MIPMAP_ENABLE 1 /**< \brief Enable mipmap processing */ +/** @} */ -#define PVR_TXRFMT_NONE 0 /* txr_format */ -#define PVR_TXRFMT_VQ_DISABLE (0 << 30) -#define PVR_TXRFMT_VQ_ENABLE (1 << 30) -#define PVR_TXRFMT_ARGB1555 (0 << 27) -#define PVR_TXRFMT_RGB565 (1 << 27) -#define PVR_TXRFMT_ARGB4444 (2 << 27) -#define PVR_TXRFMT_YUV422 (3 << 27) -#define PVR_TXRFMT_BUMP (4 << 27) -#define PVR_TXRFMT_PAL4BPP (5 << 27) -#define PVR_TXRFMT_PAL8BPP (6 << 27) -#define PVR_TXRFMT_TWIDDLED (0 << 26) -#define PVR_TXRFMT_NONTWIDDLED (1 << 26) -#define PVR_TXRFMT_NOSTRIDE (0 << 21) -#define PVR_TXRFMT_STRIDE (1 << 21) +/** \defgroup pvr_txr_fmts PVR texture formats + These are the texture formats that the PVR supports. Note that some of + these, you can OR together with other values. + + @{ +*/ +#define PVR_TXRFMT_NONE 0 /**< \brief No texture */ +#define PVR_TXRFMT_VQ_DISABLE (0 << 30) /**< \brief Not VQ encoded */ +#define PVR_TXRFMT_VQ_ENABLE (1 << 30) /**< \brief VQ encoded */ +#define PVR_TXRFMT_ARGB1555 (0 << 27) /**< \brief 16-bit ARGB1555 */ +#define PVR_TXRFMT_RGB565 (1 << 27) /**< \brief 16-bit RGB565 */ +#define PVR_TXRFMT_ARGB4444 (2 << 27) /**< \brief 16-bit ARGB4444 */ +#define PVR_TXRFMT_YUV422 (3 << 27) /**< \brief YUV422 format */ +#define PVR_TXRFMT_BUMP (4 << 27) /**< \brief Bumpmap format */ +#define PVR_TXRFMT_PAL4BPP (5 << 27) /**< \brief 4BPP paletted format */ +#define PVR_TXRFMT_PAL8BPP (6 << 27) /**< \brief 8BPP paletted format */ +#define PVR_TXRFMT_TWIDDLED (0 << 26) /**< \brief Texture is twiddled */ +#define PVR_TXRFMT_NONTWIDDLED (1 << 26) /**< \brief Texture is not twiddled */ +#define PVR_TXRFMT_NOSTRIDE (0 << 21) /**< \brief Texture is not strided */ +#define PVR_TXRFMT_STRIDE (1 << 21) /**< \brief Texture is strided */ + /* OR one of these into your texture format if you need it. Note that these coincide with the twiddled/stride bits, so you can't have a non-twiddled/strided texture that's paletted! */ -#define PVR_TXRFMT_8BPP_PAL(x) ((x) << 25) -#define PVR_TXRFMT_4BPP_PAL(x) ((x) << 21) +/** \brief 8BPP palette selector + \param x The palette index */ +#define PVR_TXRFMT_8BPP_PAL(x) ((x) << 25) -#define PVR_CLRFMT_ARGBPACKED 0 /* color_format */ -#define PVR_CLRFMT_4FLOATS 1 -#define PVR_CLRFMT_INTENSITY 2 -#define PVR_CLRFMT_INTENSITY_PREV 3 +/** \brief 4BPP palette selector + \param x The palette index */ +#define PVR_TXRFMT_4BPP_PAL(x) ((x) << 21) +/** @} */ -#define PVR_UVFMT_32BIT 0 /* txr_uv_format */ -#define PVR_UVFMT_16BIT 1 +/** \defgroup pvr_color_fmts PVR vertex color formats -#define PVR_MODIFIER_DISABLE 0 /* modifier_format */ -#define PVR_MODIFIER_ENABLE 1 + These control how colors are represented in polygon data. + @{ +*/ +#define PVR_CLRFMT_ARGBPACKED 0 /**< \brief 32-bit integer ARGB */ +#define PVR_CLRFMT_4FLOATS 1 /**< \brief 4 floating point values */ +#define PVR_CLRFMT_INTENSITY 2 /**< \brief Intensity color */ +#define PVR_CLRFMT_INTENSITY_PREV 3 /**< \brief Use last intensity */ +/** @} */ + +/** \defgroup pvr_uv_fmts PVR U/V data format control + @{ +*/ +#define PVR_UVFMT_32BIT 0 /**< \brief 32-bit floating point U/V */ +#define PVR_UVFMT_16BIT 1 /**< \brief 16-bit floating point U/V */ +/** @} */ + +/** \defgroup pvr_mod_switch Enable or disable modifier effects + @{ +*/ +#define PVR_MODIFIER_DISABLE 0 /**< \brief Disable modifier effects */ +#define PVR_MODIFIER_ENABLE 1 /**< \brief Enable modifier effects */ +/** @} */ + #define PVR_MODIFIER_CHEAP_SHADOW 0 #define PVR_MODIFIER_NORMAL 1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-05-07 19:55:00
|
Revision: 714 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=714&view=rev Author: ljsebald Date: 2011-05-07 19:54:54 +0000 (Sat, 07 May 2011) Log Message: ----------- Fix something I inadvertantly broke... Modified Paths: -------------- kos/kernel/arch/dreamcast/include/dc/vmufs.h Modified: kos/kernel/arch/dreamcast/include/dc/vmufs.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/vmufs.h 2011-05-07 15:08:49 UTC (rev 713) +++ kos/kernel/arch/dreamcast/include/dc/vmufs.h 2011-05-07 19:54:54 UTC (rev 714) @@ -371,7 +371,7 @@ You should check this number before attempting to write. - \return The number of blocks free for writing. */ + \return The number of blocks free for writing. */ int vmufs_free_blocks(maple_device_t * dev); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-05-07 15:08:56
|
Revision: 713 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=713&view=rev Author: ljsebald Date: 2011-05-07 15:08:49 +0000 (Sat, 07 May 2011) Log Message: ----------- Even more doxygen comments. Getting much closer to having everything documented... Modified Paths: -------------- kos/kernel/arch/dreamcast/include/dc/flashrom.h kos/kernel/arch/dreamcast/include/dc/scif.h kos/kernel/arch/dreamcast/include/dc/spu.h kos/kernel/arch/dreamcast/include/dc/video.h kos/kernel/arch/dreamcast/include/navi/flash.h kos/kernel/arch/dreamcast/include/navi/ide.h Modified: kos/kernel/arch/dreamcast/include/dc/flashrom.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/flashrom.h 2011-05-07 03:44:13 UTC (rev 712) +++ kos/kernel/arch/dreamcast/include/dc/flashrom.h 2011-05-07 15:08:49 UTC (rev 713) @@ -1,12 +1,27 @@ /* KallistiOS ##version## - kernel/arch/dreamcast/include/dc/flashrom.h - Copyright (C)2003 Dan Potter - Copyright (C)2008 Lawrence Sebald + dc/flashrom.h + Copyright (C) 2003 Dan Potter + Copyright (C) 2008 Lawrence Sebald */ +/** \file dc/flashrom.h + \brief Dreamcast flashrom read/write support. + This file implements wrappers for the BIOS flashrom syscalls, and some + utilities to make it easier to use the flashrom info. Note that because the + flash writing can be such a dangerous thing potentially (I haven't deleted + my flash to see what happens, but given the info stored here it sounds like + a Bad Idea(tm)) the syscalls for the WRITE and DELETE operations are not + enabled by default. If you are 100% sure you really want to be writing to + the flash and you know what you're doing, then you can edit flashrom.c and + re-enable them there. + + \author Dan Potter + \author Lawrence Sebald +*/ + #ifndef __DC_FLASHROM_H #define __DC_FLASHROM_H @@ -15,217 +30,294 @@ #include <arch/types.h> -/** - \file Implements wrappers for the BIOS flashrom syscalls, and some - utilities to make it easier to use the flashrom info. Note that - because the flash writing can be such a dangerous thing potentially - (I haven't deleted my flash to see what happens, but given the - info stored here it sounds like a Bad Idea(tm)) the syscalls for - the WRITE and DELETE operations are not enabled by default. If you - are 100% sure you really want to be writing to the flash and you - know what you're doing, then you can edit flashrom.c and re-enable - them there. */ +/** \defgroup fr_parts Partitions available in the flashrom + @{ +*/ +#define FLASHROM_PT_SYSTEM 0 /**< \brief Factory settings (read-only, 8K) */ +#define FLASHROM_PT_RESERVED 1 /**< \brief reserved (all 0s, 8K) */ +#define FLASHROM_PT_BLOCK_1 2 /**< \brief Block allocated (16K) */ +#define FLASHROM_PT_SETTINGS 3 /**< \brief Game settings (block allocated, 32K) */ +#define FLASHROM_PT_BLOCK_2 4 /**< \brief Block allocated (64K) */ +/** @} */ -/** - An enumeration of partitions available in the flashrom. */ -#define FLASHROM_PT_SYSTEM 0 /*< Factory settings (read-only, 8K) */ -#define FLASHROM_PT_RESERVED 1 /*< reserved (all 0s, 8K) */ -#define FLASHROM_PT_BLOCK_1 2 /*< Block allocated (16K) */ -#define FLASHROM_PT_SETTINGS 3 /*< Game settings (block allocated, 32K) */ -#define FLASHROM_PT_BLOCK_2 4 /*< Block allocated (64K) */ -/** - An enumeration of logical blocks available in the flashrom. */ -#define FLASHROM_B1_SYSCFG 0x05 /*< System config (BLOCK_1) */ -#define FLASHROM_B1_PW_SETTINGS_1 0x80 /*< PlanetWeb settings (BLOCK_1) */ -#define FLASHROM_B1_PW_SETTINGS_2 0x81 /*< PlanetWeb settings (BLOCK_1) */ -#define FLASHROM_B1_PW_SETTINGS_3 0x82 /*< PlanetWeb settings (BLOCK_1) */ -#define FLASHROM_B1_PW_SETTINGS_4 0x83 /*< PlanetWeb settings (BLOCK_1) */ -#define FLASHROM_B1_PW_SETTINGS_5 0x84 /*< PlanetWeb settings (BLOCK_1) */ -#define FLASHROM_B1_PW_PPP1 0xC0 /*< PlanetWeb PPP settings (BLOCK_1) */ -#define FLASHROM_B1_PW_PPP2 0xC1 /*< PlanetWeb PPP settings (BLOCK_1) */ -#define FLASHROM_B1_PW_DNS 0xC2 /*< PlanetWeb DNS settings (BLOCK_1) */ -#define FLASHROM_B1_PW_EMAIL1 0xC3 /*< PlanetWeb Email settings (BLOCK_1) */ -#define FLASHROM_B1_PW_EMAIL2 0xC4 /*< PlanetWeb Email settings (BLOCK_1) */ -#define FLASHROM_B1_PW_EMAIL_PROXY 0xC5 /*< PlanetWeb Email/Proxy settings (BLOCK_1) */ -#define FLASHROM_B1_IP_SETTINGS 0xE0 /*< IP settings for BBA (BLOCK_1) */ -#define FLASHROM_B1_EMAIL 0xE2 /*< Email address (BLOCK_1) */ -#define FLASHROM_B1_SMTP 0xE4 /*< SMTP server setting (BLOCK_1) */ -#define FLASHROM_B1_POP3 0xE5 /*< POP3 server setting (BLOCK_1) */ -#define FLASHROM_B1_POP3LOGIN 0xE6 /*< POP3 login setting (BLOCK_1) */ -#define FLASHROM_B1_POP3PASSWD 0xE7 /*< POP3 password setting + proxy (BLOCK_1) */ -#define FLASHROM_B1_PPPLOGIN 0xE8 /*< PPP username + proxy (BLOCK_1) */ -#define FLASHROM_B1_PPPPASSWD 0xE9 /*< PPP passwd (BLOCK_1) */ +/** \defgroup fr_blocks Logical blocks available in the flashrom + @{ +*/ +#define FLASHROM_B1_SYSCFG 0x05 /**< \brief System config (BLOCK_1) */ +#define FLASHROM_B1_PW_SETTINGS_1 0x80 /**< \brief PlanetWeb settings (BLOCK_1) */ +#define FLASHROM_B1_PW_SETTINGS_2 0x81 /**< \brief PlanetWeb settings (BLOCK_1) */ +#define FLASHROM_B1_PW_SETTINGS_3 0x82 /**< \brief PlanetWeb settings (BLOCK_1) */ +#define FLASHROM_B1_PW_SETTINGS_4 0x83 /**< \brief PlanetWeb settings (BLOCK_1) */ +#define FLASHROM_B1_PW_SETTINGS_5 0x84 /**< \brief PlanetWeb settings (BLOCK_1) */ +#define FLASHROM_B1_PW_PPP1 0xC0 /**< \brief PlanetWeb PPP settings (BLOCK_1) */ +#define FLASHROM_B1_PW_PPP2 0xC1 /**< \brief PlanetWeb PPP settings (BLOCK_1) */ +#define FLASHROM_B1_PW_DNS 0xC2 /**< \brief PlanetWeb DNS settings (BLOCK_1) */ +#define FLASHROM_B1_PW_EMAIL1 0xC3 /**< \brief PlanetWeb Email settings (BLOCK_1) */ +#define FLASHROM_B1_PW_EMAIL2 0xC4 /**< \brief PlanetWeb Email settings (BLOCK_1) */ +#define FLASHROM_B1_PW_EMAIL_PROXY 0xC5 /**< \brief PlanetWeb Email/Proxy settings (BLOCK_1) */ +#define FLASHROM_B1_IP_SETTINGS 0xE0 /**< \brief IP settings for BBA (BLOCK_1) */ +#define FLASHROM_B1_EMAIL 0xE2 /**< \brief Email address (BLOCK_1) */ +#define FLASHROM_B1_SMTP 0xE4 /**< \brief SMTP server setting (BLOCK_1) */ +#define FLASHROM_B1_POP3 0xE5 /**< \brief POP3 server setting (BLOCK_1) */ +#define FLASHROM_B1_POP3LOGIN 0xE6 /**< \brief POP3 login setting (BLOCK_1) */ +#define FLASHROM_B1_POP3PASSWD 0xE7 /**< \brief POP3 password setting + proxy (BLOCK_1) */ +#define FLASHROM_B1_PPPLOGIN 0xE8 /**< \brief PPP username + proxy (BLOCK_1) */ +#define FLASHROM_B1_PPPPASSWD 0xE9 /**< \brief PPP passwd (BLOCK_1) */ +/** @} */ -/** - Implements the FLASHROM_INFO syscall; given a partition ID, - return two ints specifying the beginning and the size of - the partition (respectively) inside the flashrom. Returns zero - if successful, -1 otherwise. */ +/** \brief Retrieve information about the given partition. + + This function implements the FLASHROM_INFO syscall; given a partition ID, + return two ints specifying the beginning and the size of the partition + (respectively) inside the flashrom. + + \param part The partition ID in question. + \param start_out Buffer for storing the start address. + \param size_out Buffer for storing the size of the partition. + \retval 0 On success. + \retval -1 On error. +*/ int flashrom_info(int part, int * start_out, int * size_out); -/** - Implements the FLASHROM_READ syscall; given a flashrom offset, - an output buffer, and a count, this reads data from the - flashrom. Returns the number of bytes read if successful, - or -1 otherwise. */ +/** \brief Read data from the flashrom. + + This function implements the FLASHROM_READ syscall; given a flashrom offset, + an output buffer, and a count, this reads data from the flashrom. + + \param offset The offset to read from. + \param buffer_out Space to read into. + \param bytes The number of bytes to read. + \return The number of bytes read if successful, or -1 + otherwise. +*/ int flashrom_read(int offset, void * buffer_out, int bytes); -/** - Implements the FLASHROM_WRITE syscall; given a flashrom offset, - an input buffer, and a count, this writes data to the flashrom. - Returns the number of bytes written if successful, -1 otherwise. +/** \brief Write data to the flashrom. - NOTE: It is not possible to write ones to the flashrom over zeros. - If you want to do this, you must save the old data in the flashrom, - delete it out, and save the new data back. */ + This function implements the FLASHROM_WRITE syscall; given a flashrom + offset, an input buffer, and a count, this writes data to the flashrom. + + NOTE: It is not possible to write ones to the flashrom over zeros. If you + want to do this, you must save the old data in the flashrom, delete it out, + and save the new data back. + + \param offset The offset to write at. + \param buffer The data to write. + \param bytes The number of bytes to write. + \return The number of bytes written if successful, -1 + otherwise. +*/ int flashrom_write(int offset, void * buffer, int bytes); -/** - Implements the FLASHROM_DELETE syscall; given a partition offset, - that entire partition of the flashrom will be deleted and all data - will be reset to FFs. Returns zero if successful, -1 on failure. */ +/** \brief Delete data from the flashrom. + + This function implements the FLASHROM_DELETE syscall; given a partition + offset, that entire partition of the flashrom will be deleted and all data + will be reset to 0xFF bytes. + + \param offset The partition to erase. + \retval 0 On success. + \retval -1 On error. +*/ int flashrom_delete(int offset); /* Medium-level functions */ -/** - Returns a numbered logical block from the requested partition. The newest - data is returned. 'buffer_out' must have enough room for 60 bytes of - data. */ +/** \brief Get a logical block from the specified partition. + + This function retrieves the specified block ID from the given partition. The + newest version of the data is returned. + + \param partid The partition ID to look in. + \param blockid The logical block ID to look for. + \param buffer_out Space to store the data. Must be at least 60 bytes. + \return 0 on success, <0 on error. +*/ int flashrom_get_block(int partid, int blockid, uint8 * buffer_out); /* Higher level functions */ -/** - Language settings possible in the BIOS menu. These will be returned - from flashrom_get_language(). */ -#define FLASHROM_LANG_JAPANESE 0 -#define FLASHROM_LANG_ENGLISH 1 -#define FLASHROM_LANG_GERMAN 2 -#define FLASHROM_LANG_FRENCH 3 -#define FLASHROM_LANG_SPANISH 4 -#define FLASHROM_LANG_ITALIAN 5 +/** \defgroup fr_langs Language settings possible in the BIOS menu -/** - This struct will be filled by calling the flashrom_get_syscfg call - below. */ + This set of constants will be returned as the language value in the + flashrom_syscfg_t structure. + + @{ +*/ +#define FLASHROM_LANG_JAPANESE 0 /**< \brief Japanese language code */ +#define FLASHROM_LANG_ENGLISH 1 /**< \brief English language code */ +#define FLASHROM_LANG_GERMAN 2 /**< \brief German language code */ +#define FLASHROM_LANG_FRENCH 3 /**< \brief French language code */ +#define FLASHROM_LANG_SPANISH 4 /**< \brief Spanish language code */ +#define FLASHROM_LANG_ITALIAN 5 /**< \brief Italian language code */ +/** @} */ + +/** \brief System configuration structure. + + This structure is filled in with the settings set in the BIOS from the + flashrom_get_syscfg() function. +*/ typedef struct flashrom_syscfg { - int language; /*< Language setting (see defines above) */ - int audio; /*< 0 == mono, 1 == stereo */ - int autostart; /*< 0 == off, 1 == on */ + int language; /**< \brief Language setting. + \see fr_langs */ + int audio; /**< \brief Stereo/mono setting. 0 == mono, 1 == stereo */ + int autostart; /**< \brief Autostart discs? 0 == off, 1 == on */ } flashrom_syscfg_t; -/** - Retrieves the current syscfg settings and fills them into the struct - passed in to us. */ +/** \brief Retrieve the current system configuration settings. + \param out Storage for the configuration. + \return 0 on success, <0 on error. +*/ int flashrom_get_syscfg(flashrom_syscfg_t * out); -/** - Region settings possible in the system flash (partition 0). */ -#define FLASHROM_REGION_UNKNOWN 0 -#define FLASHROM_REGION_JAPAN 1 -#define FLASHROM_REGION_US 2 -#define FLASHROM_REGION_EUROPE 3 +/** \defgroup fr_region Region settings possible in the system -/** - Retrieves the console's region code. This is still somewhat - experimental, it may not function 100% on all DCs. Returns - one of the codes above or -1 on error. */ + One of these values should be returned by flashrom_get_region(). + + @{ +*/ +#define FLASHROM_REGION_UNKNOWN 0 /**< \brief Unknown region */ +#define FLASHROM_REGION_JAPAN 1 /**< \brief Japanese region */ +#define FLASHROM_REGION_US 2 /**< \brief US/Canada region */ +#define FLASHROM_REGION_EUROPE 3 /**< \brief European region */ +/** @} */ + +/** \brief Retrieve the console's region code. + + This function attempts to find the region of the Dreamcast. It may or may + not work on 100% of Dreamcasts, apparently. + + \return A region code, or -1 on error. + \see fr_region +*/ int flashrom_get_region(); -/** - Method constants for the ispcfg struct */ -#define FLASHROM_ISP_DHCP 0 -#define FLASHROM_ISP_STATIC 1 -#define FLASHROM_ISP_DIALUP 2 -#define FLASHROM_ISP_PPPOE 4 +/** \defgroup fr_method Connection method types -/** - Valid field constants in the ispcfg structure. */ -#define FLASHROM_ISP_IP (1 << 0) -#define FLASHROM_ISP_NETMASK (1 << 1) -#define FLASHROM_ISP_BROADCAST (1 << 2) -#define FLASHROM_ISP_GATEWAY (1 << 3) -#define FLASHROM_ISP_DNS (1 << 4) -#define FLASHROM_ISP_HOSTNAME (1 << 5) -#define FLASHROM_ISP_EMAIL (1 << 6) -#define FLASHROM_ISP_SMTP (1 << 7) -#define FLASHROM_ISP_POP3 (1 << 8) -#define FLASHROM_ISP_POP3_USER (1 << 9) -#define FLASHROM_ISP_POP3_PASS (1 << 10) -#define FLASHROM_ISP_PROXY_HOST (1 << 11) -#define FLASHROM_ISP_PROXY_PORT (1 << 12) -#define FLASHROM_ISP_PPP_USER (1 << 13) -#define FLASHROM_ISP_PPP_PASS (1 << 14) -#define FLASHROM_ISP_OUT_PREFIX (1 << 15) -#define FLASHROM_ISP_CW_PREFIX (1 << 16) -#define FLASHROM_ISP_REAL_NAME (1 << 17) -#define FLASHROM_ISP_MODEM_INIT (1 << 18) -#define FLASHROM_ISP_AREA_CODE (1 << 19) -#define FLASHROM_ISP_LD_PREFIX (1 << 20) -#define FLASHROM_ISP_PHONE1 (1 << 21) -#define FLASHROM_ISP_PHONE2 (1 << 22) + These values are representative of what type of ISP is configured in the + flashrom. -/** - Flags for the ispcfg structure */ -#define FLASHROM_ISP_DIAL_AREACODE (1 << 0) -#define FLASHROM_ISP_USE_PROXY (1 << 1) -#define FLASHROM_ISP_PULSE_DIAL (1 << 2) -#define FLASHROM_ISP_BLIND_DIAL (1 << 3) + @{ +*/ +#define FLASHROM_ISP_DHCP 0 /**< \brief DHCP-based ethernet */ +#define FLASHROM_ISP_STATIC 1 /**< \brief Static IP-based ethernet */ +#define FLASHROM_ISP_DIALUP 2 /**< \brief Dialup ISP */ +#define FLASHROM_ISP_PPPOE 4 /**< \brief PPPoE-based ethernet */ +/** @} */ -/** - This struct will be filled by calling flashrom_get_ispcfg below. - Thanks to Sam Steele for the information on DreamPassport's ISP settings. - Note that this structure has been completely reworked so that it is more - generic and can support both DreamPassport and PlanetWeb's settings. */ +/** \defgroup fr_fields Valid field constants for the flashrom_ispcfg_t struct + + The valid_fields field of the flashrom_ispcfg_t will have some combination + of these ORed together to represent what data is filled in and believed + valid. + + @{ +*/ +#define FLASHROM_ISP_IP (1 << 0) /**< \brief Static IP address */ +#define FLASHROM_ISP_NETMASK (1 << 1) /**< \brief Netmask */ +#define FLASHROM_ISP_BROADCAST (1 << 2) /**< \brief Broadcast address */ +#define FLASHROM_ISP_GATEWAY (1 << 3) /**< \brief Gateway address */ +#define FLASHROM_ISP_DNS (1 << 4) /**< \brief DNS servers */ +#define FLASHROM_ISP_HOSTNAME (1 << 5) /**< \brief Hostname */ +#define FLASHROM_ISP_EMAIL (1 << 6) /**< \brief Email address */ +#define FLASHROM_ISP_SMTP (1 << 7) /**< \brief SMTP server */ +#define FLASHROM_ISP_POP3 (1 << 8) /**< \brief POP3 server */ +#define FLASHROM_ISP_POP3_USER (1 << 9) /**< \brief POP3 username */ +#define FLASHROM_ISP_POP3_PASS (1 << 10) /**< \brief POP3 password */ +#define FLASHROM_ISP_PROXY_HOST (1 << 11) /**< \brief Proxy hostname */ +#define FLASHROM_ISP_PROXY_PORT (1 << 12) /**< \brief Proxy port */ +#define FLASHROM_ISP_PPP_USER (1 << 13) /**< \brief PPP username */ +#define FLASHROM_ISP_PPP_PASS (1 << 14) /**< \brief PPP password */ +#define FLASHROM_ISP_OUT_PREFIX (1 << 15) /**< \brief Outside dial prefix */ +#define FLASHROM_ISP_CW_PREFIX (1 << 16) /**< \brief Call waiting prefix */ +#define FLASHROM_ISP_REAL_NAME (1 << 17) /**< \brief Real name */ +#define FLASHROM_ISP_MODEM_INIT (1 << 18) /**< \brief Modem init string */ +#define FLASHROM_ISP_AREA_CODE (1 << 19) /**< \brief Area code */ +#define FLASHROM_ISP_LD_PREFIX (1 << 20) /**< \brief Long distance prefix */ +#define FLASHROM_ISP_PHONE1 (1 << 21) /**< \brief Phone number 1 */ +#define FLASHROM_ISP_PHONE2 (1 << 22) /**< \brief Phone number 2 */ +/** @} */ + +/** \defgroup fr_flags Flags for the flashrom_ispcfg_t struct + + The flags field of the flashrom_ispcfg_t will have some combination of these + ORed together to represent what settings were set. + + @{ +*/ +#define FLASHROM_ISP_DIAL_AREACODE (1 << 0) /**< \brief Dial area code before number */ +#define FLASHROM_ISP_USE_PROXY (1 << 1) /**< \brief Proxy enabled */ +#define FLASHROM_ISP_PULSE_DIAL (1 << 2) /**< \brief Pulse dialing (instead of tone) */ +#define FLASHROM_ISP_BLIND_DIAL (1 << 3) /**< \brief Blind dial (don't wait for tone) */ +/** @} */ + +/** \brief ISP configuration structure. + + This structure will be filled in by flashrom_get_ispcfg() (DreamPassport) or + flashrom_get_pw_ispcfg() (PlanetWeb). Thanks to Sam Steele for the + information about DreamPassport's ISP settings. +*/ typedef struct flashrom_ispcfg { - int method; /*< DHCP, Static, dialup(?), PPPoE */ - uint32 valid_fields; /*< Which fields are valid? */ - uint32 flags; /*< Various flags that can be set in options */ + int method; /**< \brief DHCP, Static, dialup(?), PPPoE + \see fr_method */ + uint32 valid_fields; /**< \brief Which fields are valid? + \see fr_fields */ + uint32 flags; /**< \brief Various flags that can be set in options + \see fr_flags */ - uint8 ip[4]; /*< Host IP address */ - uint8 nm[4]; /*< Netmask */ - uint8 bc[4]; /*< Broadcast address */ - uint8 gw[4]; /*< Gateway address */ - uint8 dns[2][4]; /*< DNS servers (2) */ - int proxy_port; /*< Proxy server port */ - char hostname[24]; /*< DHCP/Host name */ - char email[64]; /*< Email address */ - char smtp[31]; /*< SMTP server */ - char pop3[31]; /*< POP3 server */ - char pop3_login[20]; /*< POP3 login */ - char pop3_passwd[32]; /*< POP3 passwd */ - char proxy_host[31]; /*< Proxy server hostname */ - char ppp_login[29]; /*< PPP login */ - char ppp_passwd[20]; /*< PPP password */ - char out_prefix[9]; /*< Outside dial prefix */ - char cw_prefix[9]; /*< Call waiting prefix */ - char real_name[31]; /*< The "Real Name" field of PlanetWeb */ - char modem_init[33]; /*< The modem init string to use */ - char area_code[4]; /*< The area code the user is in */ - char ld_prefix[21]; /*< The long-distance dial prefix */ - char p1_areacode[4]; /*< Phone number 1's area code */ - char phone1[26]; /*< Phone number 1 */ - char p2_areacode[4]; /*< Phone number 2's area code */ - char phone2[26]; /*< Phone number 2 */ + uint8 ip[4]; /**< \brief Host IP address */ + uint8 nm[4]; /**< \brief Netmask */ + uint8 bc[4]; /**< \brief Broadcast address */ + uint8 gw[4]; /**< \brief Gateway address */ + uint8 dns[2][4]; /**< \brief DNS servers (2) */ + int proxy_port; /**< \brief Proxy server port */ + char hostname[24]; /**< \brief DHCP/Host name */ + char email[64]; /**< \brief Email address */ + char smtp[31]; /**< \brief SMTP server */ + char pop3[31]; /**< \brief POP3 server */ + char pop3_login[20]; /**< \brief POP3 login */ + char pop3_passwd[32];/**< \brief POP3 passwd */ + char proxy_host[31]; /**< \brief Proxy server hostname */ + char ppp_login[29]; /**< \brief PPP login */ + char ppp_passwd[20]; /**< \brief PPP password */ + char out_prefix[9]; /**< \brief Outside dial prefix */ + char cw_prefix[9]; /**< \brief Call waiting prefix */ + char real_name[31]; /**< \brief The "Real Name" field of PlanetWeb */ + char modem_init[33]; /**< \brief The modem init string to use */ + char area_code[4]; /**< \brief The area code the user is in */ + char ld_prefix[21]; /**< \brief The long-distance dial prefix */ + char p1_areacode[4]; /**< \brief Phone number 1's area code */ + char phone1[26]; /**< \brief Phone number 1 */ + char p2_areacode[4]; /**< \brief Phone number 2's area code */ + char phone2[26]; /**< \brief Phone number 2 */ } flashrom_ispcfg_t; -/** - Retrieves the console's ISP settings as set by DreamPassport, if they exist. - Returns -1 on error (none of the settings can be found, or some other error), - or >=0 on success. You should check the valid_fields bitfield for the part of - the struct you want before relying on the data. */ +/** \brief Retrieve DreamPassport's ISP configuration. + + This function retrieves the console's ISP settings as set by DreamPassport, + if they exist. You should check the valid_fields bitfield for the part of + the struct you want before relying on the data. + + \param out Storage for the structure. + \retval 0 On success. + \retval -1 On error (no settings found, or other errors). +*/ int flashrom_get_ispcfg(flashrom_ispcfg_t * out); -/** - Retrieves the console's ISP settings as set by PlanetWeb (1.0 and 2.1 have - been verified to work), if they exist. Returns -1 on error (generally if the - PlanetWeb settings are non-existant) or >= 0 on success. You should check the - valid_fields bitfield for the part of the struct you want before relying on - the data. */ +/** \brief Retrieve PlanetWeb's ISP configuration. + + This function retrieves the console's ISP settings as set by PlanetWeb (1.0 + and 2.1 have been verified to work), if they exist. You should check the + valid_fields bitfield for the part of the struct you want before relying on + the data. + + \param out Storage for the structure. + \retval 0 On success. + \retval -1 On error (i.e, no PlanetWeb settings found). +*/ int flashrom_get_pw_ispcfg(flashrom_ispcfg_t *out); /* More to come later */ @@ -233,4 +325,3 @@ __END_DECLS #endif /* __DC_FLASHROM_H */ - Modified: kos/kernel/arch/dreamcast/include/dc/scif.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/scif.h 2011-05-07 03:44:13 UTC (rev 712) +++ kos/kernel/arch/dreamcast/include/dc/scif.h 2011-05-07 15:08:49 UTC (rev 713) @@ -1,10 +1,18 @@ /* KallistiOS ##version## dc/scif.h - Copyright (C)2000,2001,2004 Dan Potter + Copyright (C) 2000,2001,2004 Dan Potter */ +/** \file dc/scif.h + \brief Serial port functionality. + + This file deals with raw access to the serial port on the Dreamcast. + + \author Dan Potter +*/ + #ifndef __DC_SCIF_H #define __DC_SCIF_H @@ -14,21 +22,90 @@ #include <arch/types.h> #include <kos/dbgio.h> -/* Set serial parameters; this is not platform independent like I want - it to be, but it should be generic enough to be useful. */ +/** \brief Set serial parameters. + \param baud The bitrate to set. + \param fifo 1 to enable FIFO mode. +*/ void scif_set_parameters(int baud, int fifo); // The rest of these are the standard dbgio interface. + +/** \brief Enable or disable SCIF IRQ usage. + \param on 1 to enable IRQ usage, 0 for polled I/O. + \retval 0 On success (no error conditions defined). +*/ int scif_set_irq_usage(int on); + +/** \brief Is the SCIF port detected? Of course it is! + \return 1 +*/ int scif_detected(); + +/** \brief Initialize the SCIF port. + + This function initializes the SCIF port to a sane state. If dcload-serial is + in use, this is effectively a no-op. + + \retval 0 On success (no error conditions defined). +*/ int scif_init(); + +/** \brief Shutdown the SCIF port. + + This function disables SCIF IRQs, if they were enabled and cleans up. + + \retval 0 On success (no error conditions defined). +*/ int scif_shutdown(); + +/** \brief Read a single character from the SCIF port. + \return The character read if one is available, otherwise -1 + and errno is set to EAGAIN. +*/ int scif_read(); + +/** \brief Write a single character to the SCIF port. + \param c The character to write (only the low 8-bits are + written). + \retval 1 On success. + \retval -1 If the SCIF port is disabled (errno set to EIO). +*/ int scif_write(int c); + +/** \brief Flush any FIFO'd bytes out of the buffer. + + This function sends any bytes that have been queued up for transmission but + have not left yet in FIFO mode. + + \retval 0 On success. + \retval -1 If the SCIF port is disabled (errno set to EIO). +*/ int scif_flush(); + +/** \brief Write a whole buffer of data to the SCIF port. + + This function writes a whole buffer of data to the SCIF port, optionally + making all newlines into carriage return + newline pairs. + + \param data The buffer to write. + \param len The length of the buffer, in bytes. + \param xlat If set to 1, all newlines will be written as CRLF. + \return The number of bytes written on success, -1 on error. +*/ int scif_write_buffer(const uint8 *data, int len, int xlat); + +/** \brief Read a buffer of data from the SCIF port. + + This function reads a whole buffer of data from the SCIF port, blocking + until it has been filled. + + \param data The buffer to read into. + \param len The number of bytes to read. + \return The number of bytes read on success, -1 on error. +*/ int scif_read_buffer(uint8 *data, int len); +/** \brief SCIF debug I/O handler. Do not modify! */ extern dbgio_handler_t dbgio_scif; __END_DECLS Modified: kos/kernel/arch/dreamcast/include/dc/spu.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/spu.h 2011-05-07 03:44:13 UTC (rev 712) +++ kos/kernel/arch/dreamcast/include/dc/spu.h 2011-05-07 15:08:49 UTC (rev 713) @@ -1,10 +1,18 @@ /* KallistiOS ##version## dc/spu.h - (c)2000-2001 Dan Potter + Copyright (C) 2000-2001 Dan Potter */ +/** \file dc/spu.h + \brief Functions related to sound. + + This file deals with memory transfers and the like for the sound hardware. + + \author Dan Potter +*/ + #ifndef __DC_SPU_H #define __DC_SPU_H @@ -14,14 +22,44 @@ #include <arch/types.h> #include <dc/g2bus.h> -/* Waits for the sound FIFO to empty */ +/** \brief Waits for the sound FIFO to empty. */ void spu_write_wait(); -/* memcpy and memset designed for sound RAM; for addresses, don't - bother to include the 0xa0800000 offset that is implied. 'length' - must be a multiple of 4, but if it is not it will be rounded up. */ +/** \brief Copy a block of data to sound RAM. + + This function acts much like memcpy() but copies to the sound RAM area. + + \param to The offset in sound RAM to copy to. Do not include + the 0xA0800000 part, it is implied. + \param from A pointer to copy from. + \param length The number of bytes to copy. Automatically rounded + up to be a multiple of 4. +*/ void spu_memload(uint32 to, void *from, int length); + +/** \brief Copy a block of data from sound RAM. + + This function acts much like memcpy() but copies from the sound RAM area. + + \param to A pointer to copy to. + \param from The offset in sound RAM to copy from. Do not include + the 0xA0800000 part, it is implied. + \param length The number of bytes to copy. Automatically rounded + up to be a multiple of 4. +*/ void spu_memread(void *to, uint32 from, int length); + +/** \brief Set a block of sound RAM to the specified value. + + This function acts like memset4(), setting the specified block of sound RAM + to the given 32-bit value. + + \param to The offset in sound RAM to set at. Do not include + the 0xA0800000 part, it is implied. + \param what The value to set. + \param length The number of bytes to copy. Automatically rounded + up to be a multiple of 4. +*/ void spu_memset(uint32 to, uint32 what, int length); /* DMA copy from SH-4 RAM to SPU RAM; length must be a multiple of 32, @@ -29,33 +67,104 @@ boundaries. If block is non-zero, this function won't return until the transfer is complete. If callback is non-NULL, it will be called upon completion (in an interrupt context!). Returns <0 on error. */ + +/** \brief SPU DMA callback type. */ typedef g2_dma_callback_t spu_dma_callback_t; + +/** \brief Copy a block of data from SH4 RAM to sound RAM via DMA. + + This function sets up a DMA transfer from main RAM to the sound RAM with G2 + DMA. + + \param from A pointer in main RAM to transfer from. Must be + 32-bit aligned. + \param dest Offset in sound RAM to transfer to. Do not include + the 0xA0800000 part, its implied. Must be 32-bit + aligned. + \param length Number of bytes to copy. Must be a multiple of 32. + \param block 1 if you want to wait for the transfer to complete, + 0 otherwise (use the callback for this case). + \param callback Function to call when the DMA completes. Can be NULL + if you don't want to have a callback. This will be + called in an interrupt context, so keep that in mind + when writing the function. + \param cbdata Data to pass to the callback function. + \retval -1 On failure. Sets errno as appropriate. + \retval 0 On success. + + \par Error Conditions: + \em EINVAL - Invalid channel \n + \em EFAULT - from or dest is not aligned \n + \em EIO - I/O error +*/ int spu_dma_transfer(void * from, uint32 dest, uint32 length, int block, spu_dma_callback_t callback, ptr_t cbdata); -/* Enable/disable the SPU; note that disable implies reset of the - ARM CPU core. */ +/** \brief Enable the SPU. + + This function resets all sound channels and lets the ARM out of reset. +*/ void spu_enable(); + +/** \brief Disable the SPU. + + This function resets all sound channels and puts the ARM in a reset state. +*/ void spu_disable(); -/* Set CDDA volume: values are 0-15 */ +/** \brief Set CDDA volume. + + Valid volume values are 0-15. + + \param left_volume Volume of the left channel. + \param right_volume Volume of the right channel. +*/ void spu_cdda_volume(int left_volume, int right_volume); -/* Set CDDA panning: values are 0-31, 16=center */ +/** \brief Set CDDA panning. + + Valid values are from 0-31. 16 is centered. + + \param left_pan Pan of the left channel. + \param right_pan Pan of the right channel. +*/ void spu_cdda_pan(int left_pan, int right_pan); -/* Set master volume (0..15) and mono/stereo settings */ +/** \brief Set master mixer settings. + + This function sets the master mixer volume and mono/stereo setting. + + \param volume The volume to set (0-15). + \param stereo 1 for stereo output, 0 for mono. +*/ void spu_master_mixer(int volume, int stereo); -/* Initialize the SPU; by default it will be left in a state of - reset until you upload a program. */ +/** \brief Initialize the SPU. + + This function will reset the SPU, clear the sound RAM, reinit the CDDA + support and run an infinite loop on the ARM. + + \retval 0 On success (no error conditions defined). +*/ int spu_init(); -/* Shutdown SPU */ +/** \brief Shutdown the SPU. + + This function disables the SPU and clears sound RAM. + + \retval 0 On success (no error conditions defined). +*/ int spu_shutdown(); -/* These two are seperate because they have to be done at a different time */ +/** \brief Initialize SPU DMA support. + + This function sets up the DMA support for transfers to the sound RAM area. + + \retval 0 On success (no error conditions defined). +*/ int spu_dma_init(); + +/** \brief Shutdown SPU DMA support. */ void spu_dma_shutdown(); __END_DECLS Modified: kos/kernel/arch/dreamcast/include/dc/video.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/video.h 2011-05-07 03:44:13 UTC (rev 712) +++ kos/kernel/arch/dreamcast/include/dc/video.h 2011-05-07 15:08:49 UTC (rev 713) @@ -1,10 +1,21 @@ /* KallistiOS ##version## - * - * dc/video.h - * (c)2001 Anders Clerwall (scav) - * - */ + dc/video.h + Copyright (C) 2001 Anders Clerwall (scav) + +*/ + +/** \file dc/video.h + \brief Functions related to video output. + + This file deals with the video output hardware in the Dreamcast. There are + functions defined herein that deal with setting up the video hardware, + defining the resolution of the display, dealing with the framebuffer, etc. + + \author Anders Clerwall + \author Dan Potter +*/ + #ifndef __DC_VIDEO_H #define __DC_VIDEO_H @@ -13,132 +24,268 @@ #include <arch/types.h> -//----------------------------------------------------------------------------- -#define CT_ANY -1 // <-- Used ONLY internally with vid_mode -#define CT_VGA 0 -#define CT_RGB 2 -#define CT_COMPOSITE 3 +/** \defgroup vid_ctype Video Cable types -//----------------------------------------------------------------------------- -#define PM_RGB555 0 -#define PM_RGB565 1 -#define PM_RGB888 3 + The vid_check_cable() function will return one of this set of values to let + you know what type of cable is connected to the Dreamcast. These are also + used in the video mode settings to limit modes to certain cable types. -//----------------------------------------------------------------------------- -// These are more generic modes + @{ +*/ +#define CT_ANY -1 /**< \brief Any cable type. Used only internally. */ +#define CT_VGA 0 /**< \brief VGA Box */ +#define CT_NONE 1 /**< \brief Nothing connected */ +#define CT_RGB 2 /**< \brief RGB/SCART cable */ +#define CT_COMPOSITE 3 /**< \brief Composite cable or RF switch */ +/** @} */ +/** \defgroup vid_pmode Video pixel modes + + This set of constants control the pixel mode that the framebuffer is set to. + + @{ +*/ +#define PM_RGB555 0 /**< \brief RGB555 pixel mode (15-bit) */ +#define PM_RGB565 1 /**< \brief RGB565 pixel mode (16-bit) */ +#define PM_RGB888 3 /**< \brief RGB888 pixel mode (24-bit) */ +/** @} */ + +/** \brief Generic display modes */ enum { - DM_GENERIC_FIRST = 0x1000, - DM_320x240 = 0x1000, - DM_640x480, - DM_800x608, - DM_256x256, - DM_768x480, - DM_768x576, - DM_GENERIC_LAST = DM_768x576 + DM_GENERIC_FIRST = 0x1000, /**< \brief First valid generic mode */ + DM_320x240 = 0x1000, /**< \brief 320x240 resolution */ + DM_640x480, /**< \brief 640x480 resolution */ + DM_800x608, /**< \brief 800x608 resolution */ + DM_256x256, /**< \brief 256x256 resolution */ + DM_768x480, /**< \brief 768x480 resolution */ + DM_768x576, /**< \brief 768x576 resolution */ + DM_GENERIC_LAST = DM_768x576 /**< \brief Last valid generic mode */ }; -// OR this with the generic mode to get 4 framebuffers instead of one +/** \brief Multi-buffered mode setting. + + OR this with the generic mode to get four framebuffers instead of one. +*/ #define DM_MULTIBUFFER 0x2000 //----------------------------------------------------------------------------- // More specific modes (and actual indeces into the mode table) +/** \brief Specific display modes */ enum { - DM_INVALID = 0, - // Valid modes below - DM_320x240_VGA = 1, - DM_320x240_NTSC, - DM_640x480_VGA, - DM_640x480_NTSC_IL, - DM_800x608_VGA, - DM_640x480_PAL_IL, - DM_256x256_PAL_IL, - DM_768x480_NTSC_IL, - DM_768x576_PAL_IL, - DM_768x480_PAL_IL, - DM_320x240_PAL, - DM_320x240_VGA_MB, - DM_320x240_NTSC_MB, - DM_640x480_VGA_MB, - DM_640x480_NTSC_IL_MB, - DM_800x608_VGA_MB, - DM_640x480_PAL_IL_MB, - DM_256x256_PAL_IL_MB, - DM_768x480_NTSC_IL_MB, - DM_768x576_PAL_IL_MB, - DM_768x480_PAL_IL_MB, - DM_320x240_PAL_MB, - // The below is only for counting.. - DM_SENTINEL, - DM_MODE_COUNT + DM_INVALID = 0, /**< \brief Invalid display mode */ + // Valid modes below + DM_320x240_VGA = 1, /**< \brief 320x240 VGA 60Hz */ + DM_320x240_NTSC, /**< \brief 320x240 NTSC 60Hz */ + DM_640x480_VGA, /**< \brief 640x480 VGA 60Hz */ + DM_640x480_NTSC_IL, /**< \brief 640x480 NTSC Interlaced 60Hz */ + DM_800x608_VGA, /**< \brief 800x608 VGA 60Hz */ + DM_640x480_PAL_IL, /**< \brief 640x480 PAL Interlaced 50Hz */ + DM_256x256_PAL_IL, /**< \brief 256x256 PAL Interlaced 50Hz */ + DM_768x480_NTSC_IL, /**< \brief 768x480 NTSC Interlaced 60Hz */ + DM_768x576_PAL_IL, /**< \brief 768x576 PAL Interlaced 50Hz */ + DM_768x480_PAL_IL, /**< \brief 768x480 PAL Interlaced 50Hz */ + DM_320x240_PAL, /**< \brief 320x240 PAL 50Hz */ + DM_320x240_VGA_MB, /**< \brief 320x240 VGA 60Hz, 4FBs */ + DM_320x240_NTSC_MB, /**< \brief 320x240 NTSC 60Hz, 4FBs */ + DM_640x480_VGA_MB, /**< \brief 640x480 VGA 60Hz, 4FBs */ + DM_640x480_NTSC_IL_MB, /**< \brief 640x480 NTSC IL 60Hz, 4FBs */ + DM_800x608_VGA_MB, /**< \brief 800x608 VGA 60Hz, 4FBs */ + DM_640x480_PAL_IL_MB, /**< \brief 640x480 PAL IL 50Hz, 4FBs */ + DM_256x256_PAL_IL_MB, /**< \brief 256x256 PAL IL 50Hz, 4FBs */ + DM_768x480_NTSC_IL_MB, /**< \brief 768x480 NTSC IL 60Hz, 4FBs */ + DM_768x576_PAL_IL_MB, /**< \brief 768x576 PAL IL 50Hz, 4FBs */ + DM_768x480_PAL_IL_MB, /**< \brief 768x480 PAL IL 50Hz, 4FBs */ + DM_320x240_PAL_MB, /**< \brief 320x240 PAL 50Hz, 4FBs */ + // The below is only for counting.. + DM_SENTINEL, /**< \brief Sentinel value, for counting */ + DM_MODE_COUNT /**< \brief Number of modes */ }; -//----------------------------------------------------------------------------- +/** \brief The maximum number of framebuffers available. */ #define VID_MAX_FB 4 // <-- This should be enough -//----------------------------------------------------------------------------- // These are for the "flags" field of "vid_mode_t" -#define VID_INTERLACE 0x00000001 -#define VID_LINEDOUBLE 0x00000002 // <-- For 240 scanlines on VGA cable -#define VID_PIXELDOUBLE 0x00000004 // <-- For low-res modes (320) -#define VID_PAL 0x00000008 // <-- This sets output to 50Hz PAL if not CT_VGA +/** \defgroup vid_flags Flags for the field in vid_mode_t. -//----------------------------------------------------------------------------- -struct vid_mode { - int generic; // <-- Generic mode identifier (for vid_set_mode) - uint16 width, height; // <-- With and height of screen in pixels - uint32 flags; // <-- Combination of one or more VID_* flags - - int16 cable_type; // <-- One of CT_* - uint16 pm; // <-- Pixel Mode - - uint16 scanlines, clocks; // <-- Scanlines/frame and clocks per scanline. - uint16 bitmapx, bitmapy; // <-- Bitmap window position (bitmapy is automatically increased for PAL) - uint16 scanint1, scanint2; // <-- Scanline interrupt positions (scanint2 automatically doubled for VGA) - uint16 borderx1, borderx2; // <-- Border x start/stop - uint16 bordery1, bordery2; // <-- Border y start/stop - - uint16 fb_curr, fb_count; - uint32 fb_base[VID_MAX_FB]; -}; + These flags indicate various things related to the modes for a vid_mode_t. -typedef struct vid_mode vid_mode_t; + @{ +*/ +#define VID_INTERLACE 0x00000001 /**< \brief Interlaced display */ +#define VID_LINEDOUBLE 0x00000002 /**< \brief Display each scanline twice */ +#define VID_PIXELDOUBLE 0x00000004 /**< \brief Display each pixel twice */ +#define VID_PAL 0x00000008 /**< \brief 50Hz refresh rate, if not VGA */ +/** @} */ +/** \brief Video mode structure. + + KOS maintains a list of valid video modes internally that correspond to the + specific display modes enumeration. Each of them is built of one of these. +*/ +typedef struct vid_mode { + int generic; /**< \brief Generic mode type for vid_set_mode() */ + uint16 width; /**< \brief Width of the display, in pixels */ + uint16 height; /**< \brief Height of the display, in pixels */ + uint32 flags; /**< \brief Combination of one or more VID_* flags */ + + int16 cable_type; /**< \brief Allowed cable type */ + uint16 pm; /**< \brief Pixel mode */ + + uint16 scanlines; /**< \brief Number of scanlines */ + uint16 clocks; /**< \brief Clocks per scanline */ + uint16 bitmapx; /**< \brief Bitmap window X position */ + uint16 bitmapy; /**< \brief Bitmap window Y position (automatically + increased for PAL) */ + uint16 scanint1; /**< \brief First scanline interrupt position */ + uint16 scanint2; /**< \brief Second scanline interrupt position + (automatically doubled for VGA) */ + uint16 borderx1; /**< \brief Border X starting position */ + uint16 borderx2; /**< \brief Border X stop position */ + uint16 bordery1; /**< \brief Border Y starting position */ + uint16 bordery2; /**< \brief Border Y stop position */ + + uint16 fb_curr; /**< \brief Current framebuffer */ + uint16 fb_count; /**< \brief Number of framebuffers */ + uint32 fb_base[VID_MAX_FB]; /**< \brief Offset to framebuffers */ +} vid_mode_t; + +/** \brief The list of builtin video modes. Do not modify these! */ extern vid_mode_t vid_builtin[DM_MODE_COUNT]; + +/** \brief The current video mode. Do not modify directly! */ extern vid_mode_t *vid_mode; -//----------------------------------------------------------------------------- // These point to the current drawing area. If you're not using a multi-buffered // mode, that means they do what KOS always used to do (they'll point at the // start of VRAM). If you're using a multi-buffered mode, they'll point at the // next framebuffer to be displayed. You must use vid_flip for this to work // though (if you use vid_set_start, they'll point at the display base, for // compatibility's sake). + +/** \brief 16-bit size pointer to the current drawing area. */ extern uint16 *vram_s; + +/** \brief 32-bit size pointer to the current drawing area. */ extern uint32 *vram_l; -//----------------------------------------------------------------------------- + +/** \brief Retrieve the connected video cable type. + + This function checks the video cable and reports what it finds. + + \retval CT_VGA If a VGA Box or cable is connected. + \retval CT_NONE If nothing is connected. + \retval CT_RGB If a RGB/SCART cable is connected. + \retval CT_COMPOSITE If a composite cable or RF switch is connected. +*/ int vid_check_cable(); +/** \brief Set the VRAM base of the framebuffer. + + This function sets the vram_s and vram_l pointsers to specified offset + within VRAM and sets the start position of the framebuffer to the same + offset. + + \param base The offset within VRAM to set the base to. +*/ void vid_set_start(uint32 base); + +/** \brief Set the current framebuffer in a multibuffered setup. + + This function sets the displayed framebuffer to the specified buffer and + sets the vram_s and vram_l pointers to point at the next framebuffer, to + allow for tearing-free framebuffer-direct drawing. + + \param fb The framebuffer to display (or -1 for the next one). +*/ void vid_flip(int fb); + +/** \brief Set the border color of the display. + + This sets the color of the border area of the display. On some screens, the + border area may not be shown at all, whereas on some displays you may see + the whole thing. + + \param r The red value of the color (0-255). + \param g The green value of the color (0-255). + \param b The blue value of the color (0-255). +*/ void vid_border_color(int r, int g, int b); + +/** \brief Clear the display. + + This function sets the whole display to the specified color. Internally, + this uses the store queues to actually clear the display entirely. + + \param r The red value of the color (0-255). + \param g The green value of the color (0-255). + \param b The blue value of the color (0-255). +*/ void vid_clear(int r, int g, int b); + +/** \brief Clear VRAM. + + This function is essentially a memset() for the whole of VRAM that will + clear it all to 0 bytes. +*/ void vid_empty(); + +/** \brief Wait for VBlank. + + This function busy loops until the vertical blanking period starts. +*/ void vid_waitvbl(); + +/** \brief Set the video mode. + + This function sets the current video mode to the one specified by the + parameters. + + \param dm The display mode to use. One of the DM_* values. + \param pm The pixel mode to use. One of the PM_* values. +*/ void vid_set_mode(int dm, int pm); + +/** \brief Set the video mode. + + This function sets the current video mode to the mode structure passed in. + You can use this to add support to your program for modes that KOS doesn't + have support for built-in (of course, you should tell us the settings so we + can add them into KOS if you do this). + + \param mode A filled in vid_mode_t for the mode wanted. +*/ void vid_set_mode_ex(vid_mode_t *mode); +/** \brief Initialize the video system. + + This function initializes the video display, setting the mode to the + specified parameters, clearing vram, and setting the first framebuffer as + active. + + \param disp_mode The display mode to use. One of the DM_* values. + \param pixel_mode The pixel mode to use. One of the PM_* values. +*/ void vid_init(int disp_mode, int pixel_mode); + +/** \brief Shut down the video system. + + This function reinitializes the video system to what dcload and friends + expect it to be. +*/ void vid_shutdown(); -//----------------------------------------------------------------------------- +/** \brief Take a screenshot. + This function takes the current framebuffer (vram_s/vram_l) and dumps it out + to a PPM file. + + \param destfn The filename to save to. + \return 0 on success, <0 on failure. +*/ int vid_screen_shot(const char * destfn); -//----------------------------------------------------------------------------- - __END_DECLS #endif // __DC_VIDEO_H Modified: kos/kernel/arch/dreamcast/include/navi/flash.h =================================================================== --- kos/kernel/arch/dreamcast/include/navi/flash.h 2011-05-07 03:44:13 UTC (rev 712) +++ kos/kernel/arch/dreamcast/include/navi/flash.h 2011-05-07 15:08:49 UTC (rev 713) @@ -1,27 +1,50 @@ /* KallistiOS ##version## navi/flash.h - (c)2002 Dan Potter + Copyright (C) 2002 Dan Potter */ +/** \file navi/flash.h + \brief BIOS replacement flashrom support. + + This file is involved with accessing an flashrom chip soldered in place to + replace the BIOS ROM. Specifically, this driver is for accessing a STMicro + M29W800B, but should also work with other chips like the M29W160B or + equivalent AMD chips. + + \author Dan Potter +*/ + #ifndef __NAVI_FLASH_H #define __NAVI_FLASH_H #include <arch/types.h> -/* Return 0 if we successfully detect a compatible device */ +/** \brief Try to detect a compatible flashrom. + \return 0 if a compatible flashrom is detected, <0 if the + normal Dreamcast BIOS is detected. +*/ int nvflash_detect(); -/* Erase a block of flash */ +/** \brief Erase a single block of flashrom. + \param addr The block of the flashrom to erase. + \return 0 on success, <0 on error. +*/ int nvflash_erase_block(uint32 addr); -/* Write a block of data */ +/** \brief Write data to the flashrom. + \param addr The block of the flashrom to write to. + \param data The data to write. + \param len The length of the data, in bytes. + \return 0 on success, <0 on error. +*/ int nvflash_write_block(uint32 addr, void * data, uint32 len); /* Erase the whole flash chip */ +/** \brief Erase the whole flashrom. + \return 0 on success, <0 on error. +*/ int nvflash_erase_all(); - #endif /* __NAVI_FLASH_H */ - Modified: kos/kernel/arch/dreamcast/include/navi/ide.h =================================================================== --- kos/kernel/arch/dreamcast/include/navi/ide.h 2011-05-07 03:44:13 UTC (rev 712) +++ kos/kernel/arch/dreamcast/include/navi/ide.h 2011-05-07 15:08:49 UTC (rev 713) @@ -1,28 +1,53 @@ /* KallistiOS ##version## navi/ide.h - (c)2002 Dan Potter + Copyright (C) 2002 Dan Potter */ +/** \file navi/ide.h + \brief External G2 Bus-based IDE support. + + This file is involved with accessing an IDE controller that is attached to + the G2 Bus expansion port. Exact details of how to build such a device have + been posted in various places around the Internet. This driver refers to the + device built by Dan as a part of the Navi project. + + \author Dan Potter +*/ + #ifndef __NAVI_IDE_H #define __NAVI_IDE_H #include <arch/types.h> -/* Read n sectors from the hard disk using PIO mode */ +/** \brief Read sectors from the hard disk via PIO. + \param linear The address to begin reading from. + \param numsects The number of sectors to read. + \param bufptr The buffer to read into. + \return 0 on success, <0 on error. +*/ int ide_read(uint32 linear,uint32 numsects, void *bufptr); -/* Write n sectors to the hard disk using PIO mode */ +/** \brief Write sectors from the hard disk via PIO. + \param linear The address to begin writing to. + \param numsects The number of sectors to write. + \param bufptr The buffer to write out of. + \return 0 on success, <0 on error. +*/ int ide_write(uint32 linear,uint32 numsects, void *bufptr); -/* Get the available space */ +/** \brief Retrieve the number of sectors from the hard disk. + \returns The total number of linear sectors. +*/ uint32 ide_num_sectors(); -/* Init/Shutdown the device */ +/** \brief Initialize Navi IDE. + \return 0 on success (no error conditions defined). +*/ int ide_init(); + +/** \brief Shutdown Navi IDE. */ void ide_shutdown(); - #endif /* __NAVI_IDE_H */ - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-05-07 03:44:20
|
Revision: 712 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=712&view=rev Author: ljsebald Date: 2011-05-07 03:44:13 +0000 (Sat, 07 May 2011) Log Message: ----------- Document the net.h file... Modified Paths: -------------- kos/include/kos/net.h Modified: kos/include/kos/net.h =================================================================== --- kos/include/kos/net.h 2011-05-07 02:22:41 UTC (rev 711) +++ kos/include/kos/net.h 2011-05-07 03:44:13 UTC (rev 712) @@ -6,6 +6,18 @@ */ +/** \file kos/net.h + \brief Network support. + + This file contains declarations related to networking support. KOS' built-in + network stack supports UDP over IPv4, and to some degree has some basic IPv6 + support as well. This will change over time, hopefully leaving us with full + TCP and UDP support both over IPv4 and IPv6. + + \author Lawrence Sebald + \author Dan Potter +*/ + #ifndef __KOS_NET_H #define __KOS_NET_H @@ -20,121 +32,166 @@ -/* Structure describing one usable network device; this is pretty ethernet - centric, though I suppose you could stuff other things into this system - like PPP. */ +/** \brief Structure describing one usable network device. + + Each usable network device should have one of these describing it. These + must be registered to the network layer before the device is useable. +*/ typedef struct knetif { - /* Device list handle */ + /** \brief Device list handle (not a function!) */ LIST_ENTRY(knetif) if_list; - /* Device name ("bba", "la", etc) */ + /** \brief Device name ("bba", "la", etc) */ const char *name; - /* Long description of the device */ + /** \brief Long description of the device */ const char *descr; - /* Unit index (starts at zero and counts upwards for multiple - network devices of the same type) */ + /** \brief Unit index (starts at zero and counts upwards for multiple + network devices of the same type) */ int index; - /* Internal device ID (for whatever the driver wants) */ + /** \brief Internal device ID (for whatever the driver wants) */ uint32 dev_id; - /* Interface flags */ + /** \brief Interface flags */ uint32 flags; - /* The device's MAC address */ + /** \brief The device's MAC address */ uint8 mac_addr[6]; - /* The device's IP address (if any) */ + /** \brief The device's IP address (if any) */ uint8 ip_addr[4]; - /* The device's netmask */ + /** \brief The device's netmask */ uint8 netmask[4]; - /* The device's gateway's IP address */ + /** \brief The device's gateway's IP address */ uint8 gateway[4]; - /* The device's broadcast address */ + /** \brief The device's broadcast address */ uint8 broadcast[4]; - /* The device's DNS server address */ + /** \brief The device's DNS server address */ uint8 dns[4]; - /* The device's MTU */ + /** \brief The device's MTU */ int mtu; - /* The device's Link-local IPv6 address */ + /** \brief The device's Link-local IPv6 address */ struct in6_addr ip6_lladdr; - /* Any further IPv6 addresses the device has. The first address in this list - will always be used, unless otherwise specified */ + /** \brief Any further IPv6 addresses the device has. + The first address in this list will always be used, unless otherwise + specified. */ struct in6_addr *ip6_addrs; int ip6_addr_count; - /* The device's gateway's IPv6 address */ + /** \brief The device's gateway's IPv6 address */ struct in6_addr ip6_gateway; - /* Default MTU over IPv6 and default hop count */ + /** \brief Default MTU over IPv6 */ uint32 mtu6; + + /** \brief Default hop limit over IPv6 */ int hop_limit; /* All of the following callback functions should return a negative value on failure, and a zero or positive value on success. Some functions have special values, as noted. */ - /* Attempt to detect the device */ + /** \brief Attempt to detect the device. + \param self The network device in question. + \return 0 on success, <0 on failure. + */ int (*if_detect)(struct knetif * self); - /* Initialize the device */ + /** \brief Initialize the device. + \param self The network device in question. + \return 0 on success, <0 on failure. + */ int (*if_init)(struct knetif * self); - /* Shutdown the device */ + /** \brief Shutdown the device. + \param self The network device in question. + \return 0 on success, <0 on failure. + */ int (*if_shutdown)(struct knetif * self); - /* Start the device (after init or stop) */ + /** \brief Start the device (after init or stop). + \param self The network device in question. + \return 0 on success, <0 on failure. + */ int (*if_start)(struct knetif * self); - /* Stop (hibernate) the device */ + /** \brief Stop (hibernate) the device. + \param self The network device in question. + \return 0 on success, <0 on failure + */ int (*if_stop)(struct knetif * self); - /* Queue a packet for transmission; see special return values - below the structure */ - int (*if_tx)(struct knetif * self, const uint8 * data, int len, int blocking); + /** \brief Queue a packet for transmission. + \param self The network device in question. + \param data The packet to transmit. + \param len The length of the packet in bytes. + \param blocking 1 if we should block if needed, 0 otherwise. + \retval NETIF_TX_OK On success. + \retval NETIF_TX_ERROR On general failure. + \retval NETIF_TX_AGAIN If non-blocking and we must block to send. + */ + int (*if_tx)(struct knetif * self, const uint8 * data, int len, + int blocking); - /* Commit any queued output packets */ + /** \brief Commit any queued output packets. + \param self The network device in question. + \return 0 on success, <0 on failure. + */ int (*if_tx_commit)(struct knetif * self); - /* Poll for queued receive packets, if neccessary */ + /** \brief Poll for queued receive packets, if neccessary. + \param self The network device in question. + \return 0 on success, <0 on failure. + */ int (*if_rx_poll)(struct knetif * self); - /* Set flags; you should generally manipulate flags through here so that - the driver gets a chance to act on the info. */ + /** \brief Set flags; you should generally manipulate flags through here so + that the driver gets a chance to act on the info. + \param self The network device in question. + \param flags_and Bitmask to and with the flags. + \param flags_or Bitmask to or with the flags. + */ int (*if_set_flags)(struct knetif * self, uint32 flags_and, uint32 flags_or); - /* Set a device's multicast list */ + /** \brief Set the device's multicast list. + \param self The network device in question. + \param list The list of MAC addresses (6 * count bytes). + \param count The number of addresses in list. + */ int (*if_set_mc)(struct knetif *self, const uint8 *list, int count); } netif_t; -/* Flags for netif_t */ -#define NETIF_NO_FLAGS 0x00000000 -#define NETIF_REGISTERED 0x00000001 /* Is it registered? */ -#define NETIF_DETECTED 0x00000002 /* Is it detected? */ -#define NETIF_INITIALIZED 0x00000004 /* Has it been initialized? */ -#define NETIF_RUNNING 0x00000008 /* Has start() been called? */ -#define NETIF_PROMISC 0x00010000 /* Promiscuous mode */ -#define NETIF_NEEDSPOLL 0x01000000 /* Needs to be polled for input */ +/** \defgroup net_flags Flags for netif_t + @{ +*/ +#define NETIF_NO_FLAGS 0x00000000 /**< \brief No flags set */ +#define NETIF_REGISTERED 0x00000001 /**< \brief Is it registered? */ +#define NETIF_DETECTED 0x00000002 /**< \brief Is it detected? */ +#define NETIF_INITIALIZED 0x00000004 /**< \brief Has it been initialized? */ +#define NETIF_RUNNING 0x00000008 /**< \brief Has start() been called? */ +#define NETIF_PROMISC 0x00010000 /**< \brief Promiscuous mode */ +#define NETIF_NEEDSPOLL 0x01000000 /**< \brief Needs to be polled for input */ +/** @} */ /* Return types for if_tx */ -#define NETIF_TX_OK 0 -#define NETIF_TX_ERROR -1 -#define NETIF_TX_AGAIN -2 +#define NETIF_TX_OK 0 /**< \brief Tx success */ +#define NETIF_TX_ERROR -1 /**< \brief Tx general error */ +#define NETIF_TX_AGAIN -2 /**< \brief Retry Tx later */ /* Blocking types */ -#define NETIF_NOBLOCK 0 -#define NETIF_BLOCK 1 +#define NETIF_NOBLOCK 0 /**< \brief Don't block for Tx */ +#define NETIF_BLOCK 1 /**< \brief Blocking is OK for Tx */ - +/* \cond */ /* Define the list type */ LIST_HEAD(netif_list, knetif); @@ -143,31 +200,34 @@ #endif #define PACKED __attribute__((packed)) +/* \endcond */ -/* IPv4 Packet header */ -typedef struct { - uint8 version_ihl; - uint8 tos; - uint16 length; - uint16 packet_id; - uint16 flags_frag_offs; - uint8 ttl; - uint8 protocol; - uint16 checksum; - uint32 src; - uint32 dest; +/** \brief IPv4 Packet header */ +typedef struct ip_hdr_s { + uint8 version_ihl; /**< \brief IP version and header length */ + uint8 tos; /**< \brief Type of Service */ + uint16 length; /**< \brief Length */ + uint16 packet_id; /**< \brief Packet ID */ + uint16 flags_frag_offs; /**< \brief Flags and fragment offset */ + uint8 ttl; /**< \brief Time to live */ + uint8 protocol; /**< \brief IP protocol */ + uint16 checksum; /**< \brief IP checksum */ + uint32 src; /**< \brief Source IP address */ + uint32 dest; /**< \brief Destination IP address */ } PACKED ip_hdr_t; -/* IPv6 Packet header */ +/** \brief IPv6 Packet header */ typedef struct ipv6_hdr_s { - uint8 version_lclass; - uint8 hclass_lflow; - uint16 lclass; - uint16 length; - uint8 next_header; - uint8 hop_limit; - struct in6_addr src_addr; - struct in6_addr dst_addr; + uint8 version_lclass; /**< \brief Version and low-order class + byte */ + uint8 hclass_lflow; /**< \brief High-order class byte, low-order + flow byte */ + uint16 lclass; /**< \brief Low-order class byte */ + uint16 length; /**< \brief Length */ + uint8 next_header; /**< \brief Next header type */ + uint8 hop_limit; /**< \brief Hop limit */ + struct in6_addr src_addr; /**< \brief Source IP address */ + struct in6_addr dst_addr; /**< \brief Destination IP address */ } PACKED ipv6_hdr_t; #undef PACKED @@ -175,263 +235,486 @@ /***** net_arp.c **********************************************************/ -/* Init */ +/** \brief Init ARP. + \retval 0 On success (no error conditions defined). +*/ int net_arp_init(); -/* Shutdown */ +/** \brief Shutdown ARP. */ void net_arp_shutdown(); -/* Garbage collect timed out entries */ +/** \brief Garbage collect timed out ARP entries. + + This will be done periodically as ARP lookups are requested. + + \retval 0 On success (no error conditions defined). +*/ int net_arp_gc(); -/* Add an entry to the ARP cache manually */ +/** \brief Add an entry to the ARP cache manually. + + \param nif The network device in use. + \param mac The MAC address of the entry. + \param ip The IPv4 address of the entry. + \param timestamp The entry's timestamp. Set to 0 for a permanent + entry, otherwise set to jiffies. + \retval 0 On success (no error conditions defined). +*/ int net_arp_insert(netif_t *nif, uint8 mac[6], uint8 ip[4], uint32 timestamp); -/* Look up an entry from the ARP cache; if no entry is found, then an ARP - query will be sent and an error will be returned. If you specify a packet - with the call, it will be sent when the reply comes in. pkt should be a - simple IPv4 header, data anything that comes after it. */ +/** \brief Look up an entry from the ARP cache. + + If no entry is found, then an ARP query will be sent and an error will be + returned. If you specify a packet with the call, it will be sent when the + reply comes in. + + \param nif The network device in use. + \param ip_in The IP address to lookup. + \param mac_out Storage for the MAC address, if found. + \param pkt A simple IPv4 header, if you want to send one when a + response comes in (if not found immediately). + \param data Packet data to go with the header. + \param data_size The size of data. + \retval 0 On success. + \retval -1 A query is outstanding for that address. + \retval -2 Address not found, query generated. +*/ int net_arp_lookup(netif_t *nif, uint8 ip_in[4], uint8 mac_out[6], const ip_hdr_t *pkt, const uint8 *data, int data_size); -/* Do a reverse ARP lookup: look for an IP for a given mac address; note - that if this fails, you have no recourse. */ +/** \brief Do a reverse ARP lookup. + + This function looks for an IP for a given mac address; note that if this + fails, you have no recourse. + + \param nif The network device in use. + \param ip_out Storage for the IPv4 address. + \param mac_in The MAC address to look up. + \retval 0 On success. + \retval -1 On failure. +*/ int net_arp_revlookup(netif_t *nif, uint8 ip_out[4], uint8 mac_in[6]); -/* Receive an ARP packet and process it (called by net_input) */ +/** \brief Receive an ARP packet and process it (called by net_input). + \param nif The network device in use. + \param pkt The packet received. + \param len The length of the packet. + \retval 0 On success (no error conditions defined). +*/ int net_arp_input(netif_t *nif, const uint8 *pkt, int len); -/* Generate an ARP who-has query on the given device */ +/** \brief Generate an ARP who-has query on the given device. + \param nif The network device to use. + \param ip The IP to query. + \retval 0 On success (no error conditions defined). +*/ int net_arp_query(netif_t *nif, uint8 ip[4]); /***** net_input.c *********************************************************/ -/* Type of net input callback */ -typedef int (*net_input_func)(netif_t *, const uint8 *, int); +/** \brief Network input callback type. + \param nif The network device in use. + \param pkt The packet received. + \param len The length of the packet, in bytes. + \return 0 on success, <0 on failure. +*/ +typedef int (*net_input_func)(netif_t *nif, const uint8 *pkt, int len); -/* Where will input packets be routed? */ +/** \brief Where will input packets be routed? */ extern net_input_func net_input_target; -/* Device drivers should call this function to submit packets received - in the background; this function may or may not return immidiately - but it won't take an infinitely long time (so it's safe to call inside - interrupt handlers, etc) */ +/** \brief Device drivers should call this function to submit packets received + in the background. + + This function may or may not return immidiately but it won't take an + infinitely long time (so it's safe to call inside interrupt handlers). + + \param device The network device submitting packets. + \param data The packet to submit. + \param len The length of the packet, in bytes. + \return 0 on success, <0 on failure. +*/ int net_input(netif_t *device, const uint8 *data, int len); -/* Setup an input target; returns the old target */ +/** \brief Setup a network input target. + \param t The new target callback. + \return The old target. +*/ net_input_func net_input_set_target(net_input_func t); /***** net_icmp.c *********************************************************/ -/* Type of ping reply callback */ -typedef void (*net_echo_cb)(const uint8 *, uint16, uint64, uint8, const uint8 *, int); +/** \brief ICMPv4 echo reply callback type. + \param ip The IPv4 address the reply is from. + \param seq The sequence number of the packet. + \param delta_us The time difference, in microseconds. + \param ttl The TTL value in the packet. + \param data Any data in the packet. + \param len The length of the data, in bytes. +*/ +typedef void (*net_echo_cb)(const uint8 *ip, uint16 seq, uint64 delta_us, + uint8 ttl, const uint8 *data, int len); -/* Where will we handle possibly notifying the user of ping replies? */ +/** \brief Where will we handle possibly notifying the user of ping replies? */ extern net_echo_cb net_icmp_echo_cb; -/* Send an ICMP Echo packet to the specified IP. */ +/** \brief Send an ICMP Echo packet to the specified IP. + \param net The network device to use. + \param ipaddr The IPv4 address to send to. + \param ident A packet identifier. + \param seq A packet sequence number. + \param data Data to send with the packet. + \param size The size of the data to send. + \return 0 on success, <0 on failure. +*/ int net_icmp_send_echo(netif_t *net, const uint8 ipaddr[4], uint16 ident, uint16 seq, const uint8 *data, int size); /* Valid values for the code in the net_icmp_send_dest_unreach() function. */ -#define ICMP_PROTOCOL_UNREACHABLE 2 -#define ICMP_PORT_UNREACHABLE 3 +#define ICMP_PROTOCOL_UNREACHABLE 2 /**< \brief Protocol unreachable */ +#define ICMP_PORT_UNREACHABLE 3 /**< \brief Port unreachable */ -/* Send an ICMP Destination Unreachable packet in reply to the given message */ +/** \brief Send an ICMP Destination Unreachable packet in reply to the given + message. + \param net The network device to use. + \param code The type of message this is. + \param msg The message that caused this error. + \return 0 on success, <0 on failure. +*/ int net_icmp_send_dest_unreach(netif_t *net, uint8 code, const uint8 *msg); /* Valid values for the code in the net_icmp_send_time_exceeded() function. */ -#define ICMP_REASSEMBLY_TIME_EXCEEDED 1 +#define ICMP_REASSEMBLY_TIME_EXCEEDED 1 /**< \brief Reassembly time gone */ -/* Send an ICMP Time Exceeded packet in reply to the given message */ +/** \brief Send an ICMP Time Exceeded packet in reply to the given message. + \param net The network device to use. + \param code The type of message this is. + \param msg The message that caused this error. + \return 0 on success, <0 on failure. +*/ int net_icmp_send_time_exceeded(netif_t *net, uint8 code, const uint8 *msg); /***** net_ipv4.c *********************************************************/ -/* IPv4 statistics structure. This structure holds some basic statistics about - the IPv4 layer of the stack, and can be retrieved with the function below. */ +/** \brief IPv4 statistics structure. + This structure holds some basic statistics about the IPv4 layer of the + stack, and can be retrieved with the appropriate function. */ typedef struct net_ipv4_stats { - uint32 pkt_sent; /* Packets sent out successfully */ - uint32 pkt_send_failed; /* Packets that failed to send */ - uint32 pkt_recv; /* Packets received successfully */ - uint32 pkt_recv_bad_size; /* Packets of a bad size */ - uint32 pkt_recv_bad_chksum; /* Packets with a bad checksum */ - uint32 pkt_recv_bad_proto; /* Packets with an unknown protocol */ + uint32 pkt_sent; /** \brief Packets sent out successfully */ + uint32 pkt_send_failed; /** \brief Packets that failed to send */ + uint32 pkt_recv; /** \brief Packets received successfully */ + uint32 pkt_recv_bad_size; /** \brief Packets of a bad size */ + uint32 pkt_recv_bad_chksum; /** \brief Packets with a bad checksum */ + uint32 pkt_recv_bad_proto; /** \brief Packets with an unknown proto */ } net_ipv4_stats_t; -/* Retrieve statistics from the IPv4 layer. */ +/** \brief Retrieve statistics from the IPv4 layer. + \return The net_ipv4_stats_t structure. +*/ net_ipv4_stats_t net_ipv4_get_stats(); -/* Create a 32-bit IP address, based on the individual numbers contained - within the ip. */ +/** \brief Create a 32-bit IP address, based on the individual numbers + contained within the IP. + \param addr Array of IP address octets. + \return The address, in host byte order. +*/ uint32 net_ipv4_address(const uint8 addr[4]); -/* Parse an IP address that is packet into a uint32 into an array of the - individual bytes */ +/** \brief Parse an IP address that is packet into a uint32 into an array of + the individual bytes. + \param addr The full address, in host byte order. + \param out The output buffer. +*/ void net_ipv4_parse_address(uint32 addr, uint8 out[4]); /***** net_icmp6.c ********************************************************/ -/* Type of ping reply callback */ -typedef void (*net6_echo_cb)(const struct in6_addr *, uint16, uint64, uint8, - const uint8 *, int); +/** \brief ICMPv6 echo reply callback type. + \param ip The IPv6 address the reply is from. + \param seq The sequence number of the packet. + \param delta_us The time difference, in microseconds. + \param hlim The hop limit value in the packet. + \param data Any data in the packet. + \param len The length of the data, in bytes. +*/ +typedef void (*net6_echo_cb)(const struct in6_addr *ip, uint16 seq, + uint64 delta_us, uint8 hlim, const uint8 *data, + int len); -/* Where will we handle possibly notifying the user of ping replies? */ +/** \brief Where will we handle possibly notifying the user of ping replies? */ extern net6_echo_cb net_icmp6_echo_cb; -/* Send an ICMPv6 Echo (PING6) packet to the specified device */ +/** \brief Send an ICMPv6 Echo (PING6) packet to the specified device. + \param net The network device to use. + \param dst The address to send to. + \param ident A packet identifier. + \param seq A packet sequence number. + \param data Data to send with the packet. + \param size Length of the data, in bytes. + \return 0 on success, <0 on failure. +*/ int net_icmp6_send_echo(netif_t *net, const struct in6_addr *dst, uint16 ident, uint16 seq, const uint8 *data, int size); -/* Send a Neighbor Solicitation packet on the specified device */ +/** \brief Send a Neighbor Solicitation packet on the specified device. + \param net The network device to use. + \param dst The destination address. + \param target The target address. + \param dupdet 1 if this is for duplicate detection. + \return 0 on success, <0 on failure. +*/ int net_icmp6_send_nsol(netif_t *net, const struct in6_addr *dst, const struct in6_addr *target, int dupdet); -/* Send a Neighbor Advertisement packet on the specified device */ +/** \brief Send a Neighbor Advertisement packet on the specified device. + \param net The network device to use. + \param dst The destination address. + \param target The target address. + \param sol 1 if solicited, 0 otherwise. + \return 0 on success, <0 on failure. +*/ int net_icmp6_send_nadv(netif_t *net, const struct in6_addr *dst, const struct in6_addr *target, int sol); -/* Send a Router Solicitation request on the specified interface */ +/** \brief Send a Router Solicitation request on the specified interface. + \param net The network device to use. + \return 0 on success, <0 on failure. +*/ int net_icmp6_send_rsol(netif_t *net); /* Destination Unreachable codes -- only port unreachable really makes sense */ -#define ICMP6_DEST_UNREACH_NO_ROUTE 0 -#define ICMP6_DEST_UNREACH_PROHIBITED 1 -#define ICMP6_DEST_UNREACH_BEYOND_SCOPE 2 -#define ICMP6_DEST_UNREACH_ADDR_UNREACH 3 -#define ICMP6_DEST_UNREACH_PORT_UNREACH 4 -#define ICMP6_DEST_UNREACH_FAIL_EGRESS 5 -#define ICMP6_DEST_UNREACH_BAD_ROUTE 6 +#define ICMP6_DEST_UNREACH_NO_ROUTE 0 /**< \brief No route available */ +#define ICMP6_DEST_UNREACH_PROHIBITED 1 /**< \brief Access prohibited */ +#define ICMP6_DEST_UNREACH_BEYOND_SCOPE 2 /**< \brief Gone beyond scope */ +#define ICMP6_DEST_UNREACH_ADDR_UNREACH 3 /**< \brief Address unreachable */ +#define ICMP6_DEST_UNREACH_PORT_UNREACH 4 /**< \brief Port unreachable */ +#define ICMP6_DEST_UNREACH_FAIL_EGRESS 5 /**< \brief Egress failure */ +#define ICMP6_DEST_UNREACH_BAD_ROUTE 6 /**< \brief Bad route specified */ +/** \brief Send a destination unreachable packet on the specified interface. + \param net The network device to use. + \param code The type of message this is. + \param ppkt The message that caused this error. + \param psz Size of the original message. + \return 0 on success, <0 on failure. +*/ int net_icmp6_send_dest_unreach(netif_t *net, uint8 code, const uint8 *ppkt, int psz); /* Time Exceeded codes -- only fragment reassembly time exceeded makes sense */ -#define ICMP6_TIME_EXCEEDED_HOPS_EXC 0 -#define ICMP6_TIME_EXCEEDED_FRAGMENT 1 +#define ICMP6_TIME_EXCEEDED_HOPS_EXC 0 /**< \brief Hops exceeded */ +#define ICMP6_TIME_EXCEEDED_FRAGMENT 1 /**< \brief Reassembly time gone */ +/** \brief Send a time exceeded message on the specified interface. + \param net The network device to use. + \param code The error code. + \param ppkt The message that caused this error. + \param psz Size of the original packet. + \return 0 on success, <0 on failure. +*/ int net_icmp6_send_time_exceeded(netif_t *net, uint8 code, const uint8 *ppkt, int psz); /* Parameter Problem codes */ -#define ICMP6_PARAM_PROB_BAD_HEADER 0 -#define ICMP6_PARAM_PROB_UNK_HEADER 1 -#define ICMP6_PARAM_PROB_UNK_OPTION 2 +#define ICMP6_PARAM_PROB_BAD_HEADER 0 /**< \brief Malformed header */ +#define ICMP6_PARAM_PROB_UNK_HEADER 1 /**< \brief Unknown header */ +#define ICMP6_PARAM_PROB_UNK_OPTION 2 /**< \brief Unknown header option */ -/* Send an ICMPv6 Parameter Problem about the given packet. */ +/** \brief Send an ICMPv6 Parameter Problem about the given packet. + \param net The network device to use. + \param code The error code. + \param ptr Where in the packet is the error? + \param ppkt The message that caused the error. + \param psz Size of the original packet. + \return 0 on success, <0 on failure. +*/ int net_icmp6_send_param_prob(netif_t *net, uint8 code, uint32 ptr, const uint8 *ppkt, int psz); /***** net_ipv6.c *********************************************************/ -/* IPv6 statistics structure. This structure holds some basic statistics about - the IPv6 layer of the stack, and can be retrieved with the function below. */ +/** \brief IPv6 statistics structure. + This structure holds some basic statistics about the IPv6 layer of the + stack, and can be retrieved with the appropriate function. */ typedef struct net_ipv6_stats { - uint32 pkt_sent; /* Packets sent out successfully */ - uint32 pkt_send_failed; /* Packets that failed to send */ - uint32 pkt_recv; /* Packets received successfully */ - uint32 pkt_recv_bad_size; /* Packets of a bad size */ - uint32 pkt_recv_bad_proto; /* Packets with an unknown protocol */ - uint32 pkt_recv_bad_ext; /* Packets with an unknown ext. header */ + uint32 pkt_sent; /**< \brief Packets sent out successfully */ + uint32 pkt_send_failed; /**< \brief Packets that failed to send */ + uint32 pkt_recv; /**< \brief Packets received successfully */ + uint32 pkt_recv_bad_size; /**< \brief Packets of a bad size */ + uint32 pkt_recv_bad_proto; /**< \brief Packets with an unknown proto */ + uint32 pkt_recv_bad_ext; /**< \brief Packets with an unknown hdr */ } net_ipv6_stats_t; -/* Retrieve statistics from the IPv6 layer. */ +/** \brief Retrieve statistics from the IPv6 layer. + \return The global IPv6 stats structure. +*/ net_ipv6_stats_t net_ipv6_get_stats(); /***** net_ndp.c **********************************************************/ -/* Init */ +/** \brief Init NDP. + \retval 0 On success (no error conditions defined). +*/ int net_ndp_init(); -/* Shutdown */ +/** \brief Shutdown NDP. */ void net_ndp_shutdown(); -/* Garbage collect timed out entries */ +/** \brief Garbage collect timed out NDP entries. + This will be called periodically as NDP queries come in. +*/ void net_ndp_gc(); -/* Add an entry to the NDP cache manually */ +/** \brief Add an entry to the NDP cache. + \param nif The network device in question. + \param mac The MAC address for the entry. + \param ip The IPv6 address for the entry. + \param unsol Was this unsolicited? + \return 0 on success, <0 on failure. +*/ int net_ndp_insert(netif_t *nif, const uint8 mac[6], const struct in6_addr *ip, int unsol); -/* Look up an entry from the NDP cache; if no entry is found, then an NDP - query will be sent and an error will be returned. If you specify a packet - with the call, it will be sent when the reply comes in. pkt should be a - simple IPv6 header, data anything that comes after it. */ +/** \brief Look up an entry from the NDP cache. + + If no entry is found, then an NDP query will be sent and an error will be + returned. If you specify a packet with the call, it will be sent when the + reply comes in. + + \param net The network device to use. + \param ip The IPv6 address to query. + \param mac_out Storage for the MAC address on success. + \param pkt A simple IPv6 header, if you want to send a packet + when a reply comes in. + \param data Anything that comes after the header. + \param data_size The size of data. + \return 0 on success, <0 on failure. +*/ int net_ndp_lookup(netif_t *net, const struct in6_addr *ip, uint8 mac_out[6], const ipv6_hdr_t *pkt, const uint8 *data, int data_size); /***** net_udp.c **********************************************************/ -/* UDP statistics structure. This structure holds some basic statistics about - the UDP layer of the stack, and can be retrieved with the function below. */ +/** \brief UDP statistics structure. + This structure holds some basic statistics about the UDP layer of the stack, + and can be retrieved with the appropriate function. */ typedef struct net_udp_stats { - uint32 pkt_sent; /* Packets sent out successfully */ - uint32 pkt_send_failed; /* Packets that failed to send */ - uint32 pkt_recv; /* Packets received successfully */ - uint32 pkt_recv_bad_size; /* Packets of a bad size */ - uint32 pkt_recv_bad_chksum; /* Packets with a bad checksum */ - uint32 pkt_recv_no_sock; /* Packets with to an unopened socket */ + uint32 pkt_sent; /**< \brief Packets sent out successfully */ + uint32 pkt_send_failed; /**< \brief Packets that failed to send */ + uint32 pkt_recv; /**< \brief Packets received successfully */ + uint32 pkt_recv_bad_size; /**< \brief Packets of a bad size */ + uint32 pkt_recv_bad_chksum; /**< \brief Packets with a bad checksum */ + uint32 pkt_recv_no_sock; /**< \brief Packets with to a closed port */ } net_udp_stats_t; -/* Retrieve statistics from the UDP layer. */ +/** \brief Retrieve statistics from the UDP layer. + \return The global UDP stats struct. +*/ net_udp_stats_t net_udp_get_stats(); -/* Init */ +/** \brief Init UDP. + \retval 0 On success (no error conditions defined). +*/ int net_udp_init(); -/* Shutdown */ +/** \brief Shutdown UDP. */ void net_udp_shutdown(); /***** net_crc.c **********************************************************/ -/* Calculate a "little-endian" CRC-32 over a block of data. */ +/** \brief Calculate a "little-endian" CRC-32 over a block of data. + \param data The data to calculate over. + \param size The size of the data, in bytes. + \return The calculated CRC-32. +*/ uint32 net_crc32le(const uint8 *data, int size); -/* Calculate a "big-endian" CRC-32 over a block of data. */ +/** \brief Calculate a "big-endian" CRC-32 over a block of data. + \param data The data to calculate over. + \param size The size of the data, in bytes. + \return The calculated CRC-32. +*/ uint32 net_crc32be(const uint8 *data, int size); /***** net_multicast.c ****************************************************/ -/* Add a entry to our multicast list, autocommitting it to the network interface - in the process. */ +/** \brief Add a entry to our multicast list. + + This function will auto-commit the multicast list to the network interface + in the process. + + \param mac The MAC address to add. + \return 0 on success, <0 on failure. +*/ int net_multicast_add(const uint8 mac[6]); -/* Delete an entry from our multicast list, autocommitting in the process. */ +/** \brief Delete a entry from our multicast list. + + This function will auto-commit the multicast list to the network interface + in the process. + + \param mac The MAC address to add. + \return 0 on success, <0 on failure. +*/ int net_multicast_del(const uint8 mac[6]); -/* Check if an address is on the multicast list. Returns 0 if the address is not - on the list, -1 on error, and 1 if the address is in the list. */ +/** \brief Check if an address is on the multicast list. + \param mac The MAC address to check for. + \retval 0 The address is not in the list. + \retval 1 The address is in the list. + \retval -1 On error. +*/ int net_multicast_check(const uint8 mac[6]); -/* Init / Shutdown */ +/** \brief Init multicast support. + \return 0 on success, !0 on error. +*/ int net_multicast_init(); + +/** \brief Shutdown multicast support. */ void net_multicast_shutdown(); /***** net_core.c *********************************************************/ -/* Interface list; note: do not manipulate directly */ +/** \brief Interface list; note: do not manipulate directly! */ extern struct netif_list net_if_list; -/* Function to retrieve the list. Again, do not manipulate directly. */ +/** \brief Function to retrieve the interface list. + + Do not manipulate what this returns to you! + + \return The network interface list. +*/ struct netif_list * net_get_if_list(); -/* The default network device, used with sockets. */ +/** \brief The default network device, used with sockets (read-only). */ extern netif_t *net_default_dev; -/* Set our default device to an arbitrary device, returns the old device */ +/** \brief Set our default device to an arbitrary device. + \param n The device to set as default. + \return The old default device. +*/ netif_t *net_set_default(netif_t *n); -/* Register a network device */ +/** \brief Register a network device. + \param device The device to register. + \return 0 on success, <0 on failure. +*/ int net_reg_device(netif_t *device); -/* Unregister a network device */ +/** \brief Unregister a network device. + \param device The device to unregister. + \return 0 on success, <0 on failure. +*/ int net_unreg_device(netif_t *device); -/* Init */ +/** \brief Init network support. + \return 0 on success, <0 on failure. +*/ int net_init(); -/* Shutdown */ +/** \brief Shutdown network support. */ void net_shutdown(); __END_DECLS This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-05-07 02:22:48
|
Revision: 711 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=711&view=rev Author: ljsebald Date: 2011-05-07 02:22:41 +0000 (Sat, 07 May 2011) Log Message: ----------- Add in some more doxygen comments... Modified Paths: -------------- kos/kernel/arch/dreamcast/include/dc/net/broadband_adapter.h kos/kernel/arch/dreamcast/include/dc/net/lan_adapter.h kos/kernel/arch/dreamcast/include/dc/vmu_pkg.h kos/kernel/arch/dreamcast/include/dc/vmufs.h Modified: kos/kernel/arch/dreamcast/include/dc/net/broadband_adapter.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/net/broadband_adapter.h 2011-05-07 00:42:01 UTC (rev 710) +++ kos/kernel/arch/dreamcast/include/dc/net/broadband_adapter.h 2011-05-07 02:22:41 UTC (rev 711) @@ -1,125 +1,201 @@ /* KallistiOS ##version## - * - * dc/net/broadband_adapter.h - * - * (c)2001-2002 Dan Potter - * - */ + dc/net/broadband_adapter.h + Copyright (C) 2001-2002 Dan Potter + +*/ + +/** \file dc/net/broadband_adapter.h + \brief Broadband Adapter support. + + This file contains declarations related to support for the HIT-0400 + "Broadband Adapter". There's not really anything that users will generally + have to deal with in here. + + \author Dan Potter +*/ + #ifndef __DC_NET_BROADBAND_ADAPTER_H #define __DC_NET_BROADBAND_ADAPTER_H #include <sys/cdefs.h> __BEGIN_DECLS -/* RTL8139C register definitions */ -#define RT_IDR0 0x00 /* Mac address */ -#define RT_MAR0 0x08 /* Multicast filter */ -#define RT_TXSTATUS0 0x10 /* Transmit status (4 32bit regs) */ -#define RT_TXADDR0 0x20 /* Tx descriptors (also 4 32bit) */ -#define RT_RXBUF 0x30 /* Receive buffer start address */ -#define RT_RXEARLYCNT 0x34 /* Early Rx byte count */ -#define RT_RXEARLYSTATUS 0x36 /* Early Rx status */ -#define RT_CHIPCMD 0x37 /* Command register */ -#define RT_RXBUFTAIL 0x38 /* Current address of packet read (queue tail) */ -#define RT_RXBUFHEAD 0x3A /* Current buffer address (queue head) */ -#define RT_INTRMASK 0x3C /* Interrupt mask */ -#define RT_INTRSTATUS 0x3E /* Interrupt status */ -#define RT_TXCONFIG 0x40 /* Tx config */ -#define RT_RXCONFIG 0x44 /* Rx config */ -#define RT_TIMER 0x48 /* A general purpose counter */ -#define RT_RXMISSED 0x4C /* 24 bits valid, write clears */ -#define RT_CFG9346 0x50 /* 93C46 command register */ -#define RT_CONFIG0 0x51 /* Configuration reg 0 */ -#define RT_CONFIG1 0x52 /* Configuration reg 1 */ -#define RT_TIMERINT 0x54 /* Timer interrupt register (32 bits) */ -#define RT_MEDIASTATUS 0x58 /* Media status register */ -#define RT_CONFIG3 0x59 /* Config register 3 */ -#define RT_CONFIG4 0x5A /* Config register 4 */ -#define RT_MULTIINTR 0x5C /* Multiple interrupt select */ -#define RT_MII_TSAD 0x60 /* Transmit status of all descriptors (16 bits) */ -#define RT_MII_BMCR 0x62 /* Basic Mode Control Register (16 bits) */ -#define RT_MII_BMSR 0x64 /* Basic Mode Status Register (16 bits) */ -#define RT_AS_ADVERT 0x66 /* Auto-negotiation advertisement reg (16 bits) */ -#define RT_AS_LPAR 0x68 /* Auto-negotiation link partner reg (16 bits) */ -#define RT_AS_EXPANSION 0x6A /* Auto-negotiation expansion reg (16 bits) */ +/** \defgroup bba_regs RTL8139C Register Definitions + @{ +*/ +#define RT_IDR0 0x00 /**< \brief MAC address */ +#define RT_MAR0 0x08 /**< \brief Multicast filter */ +#define RT_TXSTATUS0 0x10 /**< \brief Transmit status (4 32bit regs) */ +#define RT_TXADDR0 0x20 /**< \brief Tx descriptors (also 4 32bit) */ +#define RT_RXBUF 0x30 /**< \brief Receive buffer start address */ +#define RT_RXEARLYCNT 0x34 /**< \brief Early Rx byte count */ +#define RT_RXEARLYSTATUS 0x36 /**< \brief Early Rx status */ +#define RT_CHIPCMD 0x37 /**< \brief Command register */ +#define RT_RXBUFTAIL 0x38 /**< \brief Current address of packet read (queue tail) */ +#define RT_RXBUFHEAD 0x3A /**< \brief Current buffer address (queue head) */ +#define RT_INTRMASK 0x3C /**< \brief Interrupt mask */ +#define RT_INTRSTATUS 0x3E /**< \brief Interrupt status */ +#define RT_TXCONFIG 0x40 /**< \brief Tx config */ +#define RT_RXCONFIG 0x44 /**< \brief Rx config */ +#define RT_TIMER 0x48 /**< \brief A general purpose counter */ +#define RT_RXMISSED 0x4C /**< \brief 24 bits valid, write clears */ +#define RT_CFG9346 0x50 /**< \brief 93C46 command register */ +#define RT_CONFIG0 0x51 /**< \brief Configuration reg 0 */ +#define RT_CONFIG1 0x52 /**< \brief Configuration reg 1 */ +#define RT_TIMERINT 0x54 /**< \brief Timer interrupt register (32 bits) */ +#define RT_MEDIASTATUS 0x58 /**< \brief Media status register */ +#define RT_CONFIG3 0x59 /**< \brief Config register 3 */ +#define RT_CONFIG4 0x5A /**< \brief Config register 4 */ +#define RT_MULTIINTR 0x5C /**< \brief Multiple interrupt select */ +#define RT_MII_TSAD 0x60 /**< \brief Transmit status of all descriptors (16 bits) */ +#define RT_MII_BMCR 0x62 /**< \brief Basic Mode Control Register (16 bits) */ +#define RT_MII_BMSR 0x64 /**< \brief Basic Mode Status Register (16 bits) */ +#define RT_AS_ADVERT 0x66 /**< \brief Auto-negotiation advertisement reg (16 bits) */ +#define RT_AS_LPAR 0x68 /**< \brief Auto-negotiation link partner reg (16 bits) */ +#define RT_AS_EXPANSION 0x6A /**< \brief Auto-negotiation expansion reg (16 bits) */ +/** @} */ -/* RTL8193C MII (media independent interface) control bits */ -#define RT_MII_AN_START 0x0200 /* Start auto-negotiation */ -#define RT_MII_AN_ENABLE 0x1000 /* Enable auto-negotiation */ -#define RT_MII_RESET 0x8000 /* Reset the MII chip */ +/** \defgroup bba_miicb RTL8139C MII (media independent interface) control bits + @{ +*/ +#define RT_MII_AN_START 0x0200 /**< \brief Start auto-negotiation */ +#define RT_MII_AN_ENABLE 0x1000 /**< \brief Enable auto-negotiation */ +#define RT_MII_RESET 0x8000 /**< \brief Reset the MII chip */ +/** @} */ -/* RTL8193C MII (media independent interface) status bits */ -#define RT_MII_LINK 0x0004 /* Link is present */ -#define RT_MII_AN_CAPABLE 0x0008 /* Can do auto negotiation */ -#define RT_MII_AN_COMPLETE 0x0020 /* Auto-negotiation complete */ -#define RT_MII_10_HALF 0x0800 /* Can do 10Mbit half duplex */ -#define RT_MII_10_FULL 0x1000 /* Can do 10Mbit full */ -#define RT_MII_100_HALF 0x2000 /* Can do 100Mbit half */ -#define RT_MII_100_FULL 0x4000 /* Can do 100Mbit full */ +/** \defgroup bba_miisb RTL8139C MII (media independent interface) status bits + @{ +*/ +#define RT_MII_LINK 0x0004 /**< \brief Link is present */ +#define RT_MII_AN_CAPABLE 0x0008 /**< \brief Can do auto negotiation */ +#define RT_MII_AN_COMPLETE 0x0020 /**< \brief Auto-negotiation complete */ +#define RT_MII_10_HALF 0x0800 /**< \brief Can do 10Mbit half duplex */ +#define RT_MII_10_FULL 0x1000 /**< \brief Can do 10Mbit full */ +#define RT_MII_100_HALF 0x2000 /**< \brief Can do 100Mbit half */ +#define RT_MII_100_FULL 0x4000 /**< \brief Can do 100Mbit full */ +/** @} */ -/* RTL8193C command bits; or these together and write teh resulting value - into CHIPCMD to execute it. */ -#define RT_CMD_RESET 0x10 -#define RT_CMD_RX_ENABLE 0x08 -#define RT_CMD_TX_ENABLE 0x04 -#define RT_CMD_RX_BUF_EMPTY 0x01 +/** \defgroup bba_cbits RTL8139C Command Bits -/* RTL8139C interrupt status bits */ -#define RT_INT_PCIERR 0x8000 /* PCI Bus error */ -#define RT_INT_TIMEOUT 0x4000 /* Set when TCTR reaches TimerInt value */ -#define RT_INT_RXFIFO_OVERFLOW 0x0040 /* Rx FIFO overflow */ -#define RT_INT_RXFIFO_UNDERRUN 0x0020 /* Packet underrun / link change */ -#define RT_INT_LINK_CHANGE 0x0020 /* Packet underrun / link change */ -#define RT_INT_RXBUF_OVERFLOW 0x0010 /* Rx BUFFER overflow */ -#define RT_INT_TX_ERR 0x0008 -#define RT_INT_TX_OK 0x0004 -#define RT_INT_RX_ERR 0x0002 -#define RT_INT_RX_OK 0x0001 + OR appropriate bit values together and write into the RT_CHIPCMD register to + execute the command. -/* Composite RX bits we check for while doing an RX interrupt */ + @{ +*/ +#define RT_CMD_RESET 0x10 /**< \brief Reset the RTL8139C */ +#define RT_CMD_RX_ENABLE 0x08 /**< \brief Enable Rx */ +#define RT_CMD_TX_ENABLE 0x04 /**< \brief Enable Tx */ +#define RT_CMD_RX_BUF_EMPTY 0x01 /**< \brief Empty the Rx buffer */ +/** @} */ + +/** \defgroup bba_ibits RTL8139C Interrupt Status bits + @{ +*/ +#define RT_INT_PCIERR 0x8000 /**< \brief PCI Bus error */ +#define RT_INT_TIMEOUT 0x4000 /**< \brief Set when TCTR reaches TimerInt value */ +#define RT_INT_RXFIFO_OVERFLOW 0x0040 /**< \brief Rx FIFO overflow */ +#define RT_INT_RXFIFO_UNDERRUN 0x0020 /**< \brief Packet underrun / link change */ +#define RT_INT_LINK_CHANGE 0x0020 /**< \brief Packet underrun / link change */ +#define RT_INT_RXBUF_OVERFLOW 0x0010 /**< \brief Rx BUFFER overflow */ +#define RT_INT_TX_ERR 0x0008 /**< \brief Tx error */ +#define RT_INT_TX_OK 0x0004 /**< \brief Tx OK */ +#define RT_INT_RX_ERR 0x0002 /**< \brief Rx error */ +#define RT_INT_RX_OK 0x0001 /**< \brief Rx OK */ + +/** \brief Composite RX bits we check for while doing an RX interrupt. */ #define RT_INT_RX_ACK (RT_INT_RXFIFO_OVERFLOW | RT_INT_RXBUF_OVERFLOW | RT_INT_RX_OK) +/** @} */ -/* RTL8139C transmit status bits */ -#define RT_TX_CARRIER_LOST 0x80000000 /* Carrier sense lost */ -#define RT_TX_ABORTED 0x40000000 /* Transmission aborted */ -#define RT_TX_OUT_OF_WINDOW 0x20000000 /* Out of window collision */ -#define RT_TX_STATUS_OK 0x00008000 /* Status ok: a good packet was transmitted */ -#define RT_TX_UNDERRUN 0x00004000 /* Transmit FIFO underrun */ -#define RT_TX_HOST_OWNS 0x00002000 /* Set to 1 when DMA operation is completed */ -#define RT_TX_SIZE_MASK 0x00001fff /* Descriptor size mask */ +/** \defgroup bba_tbits RTL8139C transmit status bits + @{ +*/ +#define RT_TX_CARRIER_LOST 0x80000000 /**< \brief Carrier sense lost */ +#define RT_TX_ABORTED 0x40000000 /**< \brief Transmission aborted */ +#define RT_TX_OUT_OF_WINDOW 0x20000000 /**< \brief Out of window collision */ +#define RT_TX_STATUS_OK 0x00008000 /**< \brief Status ok: a good packet was transmitted */ +#define RT_TX_UNDERRUN 0x00004000 /**< \brief Transmit FIFO underrun */ +#define RT_TX_HOST_OWNS 0x00002000 /**< \brief Set to 1 when DMA operation is completed */ +#define RT_TX_SIZE_MASK 0x00001fff /**< \brief Descriptor size mask */ +/** @} */ -/* RTL8139C receive status bits */ -#define RT_RX_MULTICAST 0x00008000 /* Multicast packet */ -#define RT_RX_PAM 0x00004000 /* Physical address matched */ -#define RT_RX_BROADCAST 0x00002000 /* Broadcast address matched */ -#define RT_RX_BAD_SYMBOL 0x00000020 /* Invalid symbol in 100TX packet */ -#define RT_RX_RUNT 0x00000010 /* Packet size is <64 bytes */ -#define RT_RX_TOO_LONG 0x00000008 /* Packet size is >4K bytes */ -#define RT_RX_CRC_ERR 0x00000004 /* CRC error */ -#define RT_RX_FRAME_ALIGN 0x00000002 /* Frame alignment error */ -#define RT_RX_STATUS_OK 0x00000001 /* Status ok: a good packet was received */ +/** \defgroup bba_rbits RTL8139C receive status bits + @{ +*/ +#define RT_RX_MULTICAST 0x00008000 /**< \brief Multicast packet */ +#define RT_RX_PAM 0x00004000 /**< \brief Physical address matched */ +#define RT_RX_BROADCAST 0x00002000 /**< \brief Broadcast address matched */ +#define RT_RX_BAD_SYMBOL 0x00000020 /**< \brief Invalid symbol in 100TX packet */ +#define RT_RX_RUNT 0x00000010 /**< \brief Packet size is <64 bytes */ +#define RT_RX_TOO_LONG 0x00000008 /**< \brief Packet size is >4K bytes */ +#define RT_RX_CRC_ERR 0x00000004 /**< \brief CRC error */ +#define RT_RX_FRAME_ALIGN 0x00000002 /**< \brief Frame alignment error */ +#define RT_RX_STATUS_OK 0x00000001 /**< \brief Status ok: a good packet was received */ +/** @} */ -/* Reads the MAC address of the BBA into the specified array */ +/** \brief Retrieve the MAC Address of the attached BBA. + + This function reads the MAC Address of the BBA and places it in the buffer + passed in. The resulting data is undefined if no BBA is connected. + + \param arr The array to read the MAC into. +*/ void bba_get_mac(uint8 *arr); -/* Set an ethernet packet receive callback */ +/** \brief Receive packet callback function type. + + When a packet is received by the BBA, the callback function will be called + to handle it. + + \param pkt A pointer to the packet in question. + \param len The length, in bytes, of the packet. +*/ typedef void (*eth_rx_callback_t)(uint8 *pkt, int len); + +/** \brief Set the ethernet packet receive callback. + + This function sets the function called when a packet is received by the BBA. + Generally, this inputs into the network layer. + + \param cb A pointer to the new callback function. +*/ void bba_set_rx_callback(eth_rx_callback_t cb); -/* Transmit a single packet */ -#define BBA_TX_OK 0 -#define BBA_TX_ERROR -1 -#define BBA_TX_AGAIN -2 -#define BBA_TX_NOWAIT 0 -#define BBA_TX_WAIT 1 +/** \defgroup bba_txrv Return values from bba_tx(). + @{ +*/ +#define BBA_TX_OK 0 /**< \brief Transmit success */ +#define BBA_TX_ERROR -1 /**< \brief Transmit error */ +#define BBA_TX_AGAIN -2 /**< \brief Retry transmit again */ +/** @} */ + +#define BBA_TX_NOWAIT 0 /**< \brief Don't block waiting for the transfer. */ +#define BBA_TX_WAIT 1 /**< \brief Wait, if needed on transfer. */ + +/** \brief Transmit a single packet. + + This function transmits a single packet on the bba, waiting for the link to + become stable, if requested. + + \param pkt The packet to transmit. + \param len The length of the packet, in bytes. + \param wait BBA_TX_WAIT if you don't mind blocking for the + all clear to transmit, BBA_TX_NOWAIT otherwise. + + \retval BBA_TX_OK On success. + \retval BBA_TX_ERROR If there was an error transmitting the packet. + \retval BBA_TX_AGAIN If BBA_TX_NOWAIT was specified and it is not ok to + transmit right now. +*/ int bba_tx(const uint8 *pkt, int len, int wait); +/* \cond */ /* Initialize */ int bba_init(); /* Shutdown */ int bba_shutdown(); +/* \endcond */ __END_DECLS Modified: kos/kernel/arch/dreamcast/include/dc/net/lan_adapter.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/net/lan_adapter.h 2011-05-07 00:42:01 UTC (rev 710) +++ kos/kernel/arch/dreamcast/include/dc/net/lan_adapter.h 2011-05-07 02:22:41 UTC (rev 711) @@ -1,11 +1,20 @@ /* KallistiOS ##version## - * - * dc/net/lan_adapter.h - * - * (c)2002 Dan Potter - * - */ + dc/net/lan_adapter.h + Copyright (C) 2002 Dan Potter + +*/ + +/** \file dc/net/lan_adapter.h + \brief LAN Adapter support. + + This file contains declarations related to support for the HIT-0300 "LAN + Adapter". There's not really anything that users will generally have to deal + with in here. + + \author Dan Potter +*/ + #ifndef __DC_NET_LAN_ADAPTER_H #define __DC_NET_LAN_ADAPTER_H @@ -14,11 +23,13 @@ #include <kos/net.h> +/* \cond */ /* Initialize */ int la_init(); /* Shutdown */ int la_shutdown(); +/* \endcond */ __END_DECLS Modified: kos/kernel/arch/dreamcast/include/dc/vmu_pkg.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/vmu_pkg.h 2011-05-07 00:42:01 UTC (rev 710) +++ kos/kernel/arch/dreamcast/include/dc/vmu_pkg.h 2011-05-07 02:22:41 UTC (rev 711) @@ -1,10 +1,21 @@ /* KallistiOS ##version## dc/vmu_pkg.h - (c)2002 Dan Potter + Copyright (C) 2002 Dan Potter */ +/** \file dc/vmu_pkg.h + \brief VMU Packaging functionality. + + This file provides declarations for managing the headers that must be + attached to VMU files for the BIOS to pay attention to them. This does not + handle reading/writing files directly. + + \author Dan Potter + \see dc/fs_vmu.h +*/ + #ifndef __DC_VMU_PKG_H #define __DC_VMU_PKG_H @@ -13,52 +24,81 @@ #include <arch/types.h> -/* Anyone wanting to package a VMU file should create one of these - somewhere; eventually it will be turned into a flat file that you - can save using fs_vmu. */ +/** \brief VMU Package type. + + Anyone wanting to package a VMU file should create one of these somewhere; + eventually it will be turned into a flat file that you can save using + fs_vmu. +*/ typedef struct vmu_pkg { - char desc_short[20]; /* Short file description */ - char desc_long[36]; /* Long file description */ - char app_id[20]; /* Application ID */ - int icon_cnt; /* Number of icons */ - int icon_anim_speed; /* Icon animation speed */ - int eyecatch_type; /* "Eyecatch" type */ - int data_len; /* Number of data (payload) bytes */ - uint16 icon_pal[16]; /* Icon palette (ARGB4444) */ - const uint8 *icon_data; /* 512*n bytes of icon data */ - const uint8 *eyecatch_data; /* Eyecatch data */ - const uint8 *data; /* Payload data */ + char desc_short[20]; /**< \brief Short file description */ + char desc_long[36]; /**< \brief Long file description */ + char app_id[20]; /**< \brief Application ID */ + int icon_cnt; /**< \brief Number of icons */ + int icon_anim_speed; /**< \brief Icon animation speed */ + int eyecatch_type; /**< \brief "Eyecatch" type */ + int data_len; /**< \brief Number of data (payload) bytes */ + uint16 icon_pal[16]; /**< \brief Icon palette (ARGB4444) */ + const uint8 *icon_data; /**< \brief 512*n bytes of icon data */ + const uint8 *eyecatch_data; /**< \brief Eyecatch data */ + const uint8 *data; /**< \brief Payload data */ } vmu_pkg_t; -/* Final header format (will go into the VMU file itself) */ +/** \brief Final VMU package type. + + This structure will be written into the file itself, not vmu_pkg_t. +*/ typedef struct vmu_hdr { - char desc_short[16]; /* Space-padded */ - char desc_long[32]; /* Space-padded */ - char app_id[16]; /* Null-padded */ - uint16 icon_cnt; - uint16 icon_anim_speed; - uint16 eyecatch_type; - uint16 crc; - uint32 data_len; - uint8 reserved[20]; - uint16 icon_pal[16]; - /* 512*n Icon Bitmaps */ - /* Eyecatch palette + bitmap */ + char desc_short[16]; /**< \brief Space-padded short description */ + char desc_long[32]; /**< \brief Space-padded long description*/ + char app_id[16]; /**< \brief Null-padded application ID */ + uint16 icon_cnt; /**< \brief Number of icons */ + uint16 icon_anim_speed; /**< \brief Icon animation speed */ + uint16 eyecatch_type; /**< \brief Eyecatch type */ + uint16 crc; /**< \brief CRC of the file */ + uint32 data_len; /**< \brief Payload size */ + uint8 reserved[20]; /**< \brief Reserved (all zero) */ + uint16 icon_pal[16]; /**< \brief Icon palette (ARGB4444) */ + /* 512*n Icon Bitmaps */ + /* Eyecatch palette + bitmap */ } vmu_hdr_t; -/* Eyecatch types: all eyecatches are 72x56, but the pixel format is variable: */ -#define VMUPKG_EC_NONE 0 -#define VMUPKG_EC_16BIT 1 /* 16-bit ARGB4444 */ -#define VMUPKG_EC_256COL 2 /* 256-color palette */ -#define VMUPKG_EC_16COL 3 /* 16-color palette */ -/* Note that in all of the above cases which use a palette, the palette entries - are in ARGB4444 format and come directly before the pixel data itself. */ +/** \defgroup vmu_ectype Eyecatch types. -/* Converts a vmu_pkg_t structure into an array of uint8's which may be - written to a VMU file via fs_vmu, or whatever. */ + All eyecatches are 72x56, but the pixel format is variable. Note that in all + of the cases which use a palette, the palette entries are in ARGB4444 format + and come directly before the pixel data itself. + + @{ +*/ +#define VMUPKG_EC_NONE 0 /**< \brief No eyecatch */ +#define VMUPKG_EC_16BIT 1 /**< \brief 16-bit ARGB4444 */ +#define VMUPKG_EC_256COL 2 /**< \brief 256-color palette */ +#define VMUPKG_EC_16COL 3 /**< \brief 16-color palette */ +/** @} */ + +/** \brief Convert a vmu_pkg_t into an array of uint8s. + + This function converts a vmu_pkg_t structure into an array of uint8's which + may be written to a VMU file via fs_vmu, or whatever. + + \param src The vmu_pkg_t to convert. + \param dst The buffer (will be allocated for you). + \param dst_size The size of the output. + \return 0 on success, <0 on failure. +*/ int vmu_pkg_build(vmu_pkg_t *src, uint8 ** dst, int * dst_size); -/* Parse an array of uint8's (i.e. a VMU data file) into a - * vmu_pkg_t package structure. */ + +/** \brief Parse an array of uint8s into a vmu_pkg_t. + + This function does the opposite of vmu_pkg_build and is used to parse VMU + files read in. + + \param data The buffer to parse. + \param pkg Where to store the vmu_pkg_t. + \retval -1 On invalid CRC in the data. + \retval 0 On success. +*/ int vmu_pkg_parse(uint8 *data, vmu_pkg_t *pkg); Modified: kos/kernel/arch/dreamcast/include/dc/vmufs.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/vmufs.h 2011-05-07 00:42:01 UTC (rev 710) +++ kos/kernel/arch/dreamcast/include/dc/vmufs.h 2011-05-07 02:22:41 UTC (rev 711) @@ -1,10 +1,26 @@ /* KallistiOS ##version## dc/vmufs.h - Copyright (C)2003 Dan Potter + Copyright (C) 2003 Dan Potter */ +/** \file dc/vmufs.h + \brief Low-level VMU filesystem driver. + + The VMU filesystem driver mounts itself on /vmu of the VFS. Each memory card + has its own subdirectory off of that directory (i.e, /vmu/a1 for slot 1 of + the first controller). VMUs themselves have no subdirectories, so the driver + itself is fairly simple. + + Files on a VMU must be multiples of 512 bytes in size, and should have a + header attached so that they show up in the BIOS menu. + + \author Dan Potter + \see dc/vmu_pkg.h + \see dc/fs_vmu.h +*/ + #ifndef __DC_VMUFS_H #define __DC_VMUFS_H @@ -13,48 +29,51 @@ #include <dc/maple.h> +/* \cond */ #define __packed__ __attribute__((packed)) -/** BCD timestamp, used several places below */ +/* \endcond */ + +/** \brief BCD timestamp, used several places in the vmufs. */ typedef struct { - uint8 cent; - uint8 year; - uint8 month; - uint8 day; - uint8 hour; - uint8 min; - uint8 sec; - uint8 dow; /* Day of week (0 = monday, etc) */ + uint8 cent; /**< \brief Century */ + uint8 year; /**< \brief Year, within century */ + uint8 month; /**< \brief Month of the year */ + uint8 day; /**< \brief Day of the month */ + uint8 hour; /**< \brief Hour of the day */ + uint8 min; /**< \brief Minutes */ + uint8 sec; /**< \brief Seconds */ + uint8 dow; /**< \brief Day of week (0 = monday, etc) */ } __packed__ vmu_timestamp_t; -/** Root block layout */ +/** \brief VMU FS Root block layout. */ typedef struct { - uint8 magic[16]; /*< All should contain 0x55 */ - uint8 use_custom; /*< 0 = standard, 1 = custom */ - uint8 custom_color[4]; /*< blue, green, red, alpha */ - uint8 pad1[27]; /*< All zeros */ - vmu_timestamp_t timestamp; /*< BCD timestamp */ - uint8 pad2[8]; /*< All zeros */ - uint8 unk1[6]; /*< ??? */ - uint16 fat_loc ; /*< FAT location */ - uint16 fat_size; /*< FAT size in blocks */ - uint16 dir_loc; /*< Directory location */ - uint16 dir_size; /*< Directory size in blocks */ - uint16 icon_shape; /*< Icon shape for this VMS */ - uint16 blk_cnt; /*< Number of user blocks */ - uint8 unk2[430]; /*< ??? */ + uint8 magic[16]; /**< \brief All should contain 0x55 */ + uint8 use_custom; /**< \brief 0 = standard, 1 = custom */ + uint8 custom_color[4];/**< \brief blue, green, red, alpha */ + uint8 pad1[27]; /**< \brief All zeros */ + vmu_timestamp_t timestamp; /**< \brief BCD timestamp */ + uint8 pad2[8]; /**< \brief All zeros */ + uint8 unk1[6]; /**< \brief ??? */ + uint16 fat_loc; /**< \brief FAT location */ + uint16 fat_size; /**< \brief FAT size in blocks */ + uint16 dir_loc; /**< \brief Directory location */ + uint16 dir_size; /**< \brief Directory size in blocks */ + uint16 icon_shape; /**< \brief Icon shape for this VMS */ + uint16 blk_cnt; /**< \brief Number of user blocks */ + uint8 unk2[430]; /**< \brief ??? */ } __packed__ vmu_root_t; -/** Directory entries, 32 bytes each */ +/** \brief VMU FS Directory entries, 32 bytes each. */ typedef struct { - uint8 filetype; /*< 0x00 = no file; 0x33 = data; 0xcc = a game */ - uint8 copyprotect; /*< 0x00 = copyable; 0xff = copy protected */ - uint16 firstblk; /*< Location of the first block in the file */ - char filename[12]; /*< Note: there is no null terminator */ - vmu_timestamp_t timestamp; /*< File time */ - uint16 filesize; /*< Size of the file in blocks */ - uint16 hdroff; /*< Offset of header, in blocks from start of file */ - uint8 dirty; /*< See header notes */ - uint8 pad1[3]; /*< All zeros */ + uint8 filetype; /**< \brief 0x00 = no file; 0x33 = data; 0xcc = a game */ + uint8 copyprotect; /**< \brief 0x00 = copyable; 0xff = copy protected */ + uint16 firstblk; /**< \brief Location of the first block in the file */ + char filename[12]; /**< \brief Note: there is no null terminator */ + vmu_timestamp_t timestamp; /**< \brief File time */ + uint16 filesize; /**< \brief Size of the file in blocks */ + uint16 hdroff; /**< \brief Offset of header, in blocks from start of file */ + uint8 dirty; /**< \brief See header notes */ + uint8 pad1[3]; /**< \brief All zeros */ } __packed__ vmu_dir_t; #undef __packed__ @@ -74,129 +93,301 @@ /* ****************** Low level functions ******************** */ -/** Fill in the date on a vmu_dir_t for writing */ +/** \brief Fill in the date on a vmu_dir_t for writing. + + \param d The directory to fill in the date on. +*/ void vmufs_dir_fill_time(vmu_dir_t *d); -/** Reads a selected VMU's root block. Assumes the mutex is held. */ +/** \brief Reads a selected VMU's root block. + + This function assumes the mutex is held. + + \param dev The VMU to read from. + \param root_buf A buffer to hold the root block. You must allocate + this yourself before calling. + \retval -1 On failure. + \retval 0 On success. +*/ int vmufs_root_read(maple_device_t * dev, vmu_root_t * root_buf); -/** Writes a selected VMU's root block. Assumes the mutex is held. */ +/** \brief Writes a selected VMU's root block. + + This function assumes the mutex is held. + + \param dev The VMU to write to. + \param root_buf The root block to write. + \retval -1 On failure. + \retval 0 On success. +*/ int vmufs_root_write(maple_device_t * dev, vmu_root_t * root_buf); -/** Given a VMU's root block, return the amount of space in bytes required - to hold its directory. */ +/** \brief Given a VMU's root block, return the amount of space in bytes + required to hold its directory. + + \param root_buf The root block to check. + \return The amount of space, in bytes, needed. +*/ int vmufs_dir_blocks(vmu_root_t * root_buf); -/** Given a VMU's root block, return the amount of space in bytes required - to hold its FAT. */ +/** \brief Given a VMU's root block, return the amount of space in bytes + required to hold its FAT. + + \param root_buf The root block to check. + \return The amount of space, in bytes, needed. +*/ int vmufs_fat_blocks(vmu_root_t * root_buf); -/** Given a selected VMU's root block, read its directory. Assumes the mutex - is held. There must be at least the number of bytes returned by - vmufs_dir_blocks() available in the buffer for this to succeed. */ -int vmufs_dir_read(maple_device_t * dev, vmu_root_t * root_buf, vmu_dir_t * dir_buf); +/** \brief Given a selected VMU's root block, read its directory. + + This function reads the directory of a given VMU root block. It assumes the + mutex is held. There must be at least the number of bytes returned by + vmufs_dir_blocks() available in the buffer for this to succeed. -/** Given a selected VMU's root block and dir blocks, write the dirty dir blocks - back to the VMU. Assumes the mutex is held. */ -int vmufs_dir_write(maple_device_t * dev, vmu_root_t * root, vmu_dir_t * dir_buf); + \param dev The VMU to read. + \param root_buf The VMU's root block. + \param dir_buf The buffer to hold the directory. You must have + allocated this yourself. + \return 0 on success, <0 on failure. +*/ +int vmufs_dir_read(maple_device_t * dev, vmu_root_t * root_buf, + vmu_dir_t * dir_buf); -/** Given a selected VMU's root block, read its FAT. Assumes the mutex is held. - There must be at least the number of bytes returned by vmufs_fat_blocks() - available in the buffer for this to succeed. */ +/** \brief Given a selected VMU's root block and dir blocks, write the dirty + dir blocks back to the VMU. Assumes the mutex is held. + + \param dev The VMU to write to. + \param root The VMU's root block. + \param dir_buf The VMU's directory structure. + \return 0 on success, <0 on failure. +*/ +int vmufs_dir_write(maple_device_t * dev, vmu_root_t * root, + vmu_dir_t * dir_buf); + +/** \brief Given a selected VMU's root block, read its FAT. + + This function reads the FAT of a VMU, given its root block. It assumes the + mutex is held. There must be at least the number of bytes returned by + vmufs_fat_blocks() available in the buffer for this to succeed. + + \param dev The VMU to read from. + \param root The VMU's root block. + \param fat_buf The buffer to store the FAT into. You must + pre-allocate this. + \return 0 on success, <0 on failure. +*/ int vmufs_fat_read(maple_device_t * dev, vmu_root_t * root, uint16 * fat_buf); -/** Given a selected VMU's root block and its FAT, write the FAT blocks - back to the VMU. Assumes the mutex is held. */ +/** \brief Given a selected VMU's root block and its FAT, write the FAT blocks + back to the VMU. + + This function assumes the mutex is held. + + \param dev The VMU to write to. + \param root The VMU's root block. + \param fat_buf The buffer to write to the FAT. + \return 0 on success, <0 on failure. +*/ int vmufs_fat_write(maple_device_t * dev, vmu_root_t * root, uint16 * fat_buf); -/** Given a previously-read directory, locate a file by filename. The index into - the directory array will be returned on success, or <0 on failure. 'fn' will - be checked up to 12 characters. */ +/** \brief Given a previously-read directory, locate a file by filename. + + \param root The VMU root block. + \param dir The VMU directory. + \param fn The file to find (only checked up to 12 chars). + \return The index into the directory array on success, or + <0 on failure. +*/ int vmufs_dir_find(vmu_root_t * root, vmu_dir_t * dir, const char * fn); -/** Given a previously-read directory, add a new dirent to the dir. Another file - with the same name should not exist (delete it first if it does). This function - will _not_ check for dups! Returns 0 on success, or <0 on failure. */ +/** \brief Given a previously-read directory, add a new dirent to the dir. + + Another file with the same name should not exist (delete it first if it + does). This function will not check for dupes! + + \param root The VMU root block. + \param dir The VMU directory. + \param newdirent The new entry to add. + \return 0 on success, or <0 on failure. */ int vmufs_dir_add(vmu_root_t * root, vmu_dir_t * dir, vmu_dir_t * newdirent); -/** Given a pointer to a directory struct and a previously loaded FAT, load - the indicated file from the VMU. An appropriate amount of space must - have been allocated previously in the buffer. Assumes the mutex is held. - Returns 0 on success, <0 on failure. */ +/** \brief Given a pointer to a directory struct and a previously loaded FAT, + load the indicated file from the VMU. + + An appropriate amount of space must have been allocated previously in the + buffer. Assumes the mutex is held. + + \param dev The VMU to read from. + \param fat The FAT of the VMU. + \param dirent The entry to read. + \param outbuf A buffer to write the data into. You must allocate + this yourself with the appropriate amount of space. + \return 0 on success, <0 on failure. +*/ int vmufs_file_read(maple_device_t * dev, uint16 * fat, vmu_dir_t * dirent, void * outbuf); -/** Given a pointer to a mostly-filled directory struct and a previously loaded - directory and FAT, write the indicated file to the VMU. The named file - should not exist in the directory already. The directory and FAT will _not_ - be sync'd back to the VMU, this must be done manually. Assumes the mutex - is held. Returns 0 on success, <0 on failure. The 'size' parameter is in - blocks (512-bytes each). */ +/** \brief Given a pointer to a mostly-filled directory struct and a previously + loaded directory and FAT, write the indicated file to the VMU. + + The named file should not exist in the directory already. The directory and + FAT will _not_ be sync'd back to the VMU, this must be done manually. + Assumes the mutex is held. + + \param dev The VMU to write to. + \param root The VMU root block. + \param fat The FAT of the VMU. + \param dir The directory of the VMU. + \param newdirent The new entry to write. + \param filebuf The new file data. + \param size The size of the file in blocks (512-bytes each). + \return 0 on success, <0 on failure. +*/ int vmufs_file_write(maple_device_t * dev, vmu_root_t * root, uint16 * fat, vmu_dir_t * dir, vmu_dir_t * newdirent, void * filebuf, int size); -/** Given a previously-read FAT and directory, delete the named file. No changes are - made to the VMU itself, just the in-memory structs. */ +/** \brief Given a previously-read FAT and directory, delete the named file. + + No changes are made to the VMU itself, just the in-memory structs. + + \param root The VMU root block. + \param fat The FAT to be modified. + \param dir The directory to be modified. + \param fn The file name to be deleted. + \retval 0 On success. + \retval -1 If fn is not found. +*/ int vmufs_file_delete(vmu_root_t * root, uint16 * fat, vmu_dir_t * dir, const char *fn); -/** Given a previously-read FAT, return the number of blocks available to write - out new file data. */ +/** \brief Given a previously-read FAT, return the number of blocks available + to write out new file data. + + \param root The VMU root block. + \param fat The FAT to be examined. + \return The number of blocks available. +*/ int vmufs_fat_free(vmu_root_t * root, uint16 * fat); -/** Given a previously-read directory, return the number of dirents available - for new files. */ +/** \brief Given a previously-read directory, return the number of dirents + available for new files. + + \param root The VMU root block. + \param dir The directory in question. + \return The number of entries available. +*/ int vmufs_dir_free(vmu_root_t * root, vmu_dir_t * dir); -/** Lock the mutex. This should be done before you attempt any low-level ops. */ +/** \brief Lock the vmufs mutex. + + This should be done before you attempt any low-level ops. + + \retval 0 On success (no error conditions defined). +*/ int vmufs_mutex_lock(); -/** Unlock the mutex. This should be done once you're done with any low-level ops. */ +/** \brief Unlock the vmufs mutex. + + This should be done once you're done with any low-level ops. + + \retval 0 On success (no error conditions defined). +*/ int vmufs_mutex_unlock(); /* ****************** Higher level functions ******************** */ -/** Reads the directory from a VMU. The output buffer will be allocated for - you using malloc(), and the number of entries will be returned. Returns - 0 on success, or <0 on failure. On failure, 'outbuf' will not contain - a dangling buffer that needs to be freed (no further action required). */ +/** \brief Read the directory from a VMU. + + The output buffer will be allocated for you using malloc(), and the number + of entries will be returned. On failure, outbuf will not contain a dangling + buffer that needs to be freed (no further action required). + + \param dev The VMU to read from. + \param outbuf A buffer that will be allocated where the directory + data will be placed. + \param outcnt The number of entries in outbuf. + \return 0 on success, or <0 on failure. */ int vmufs_readdir(maple_device_t * dev, vmu_dir_t ** outbuf, int * outcnt); -/** Reads a file from the VMU. The output buffer will be allocated for you - using malloc(), and the size of the file will be returned. Returns 0 on - success, or <0 on failure. On failure, 'outbuf' will not contain - a dangling buffer that needs to be freed (no further action required). */ +/** \brief Read a file from the VMU. + + The output buffer will be allocated for you using malloc(), and the size of + the file will be returned. On failure, outbuf will not contain a dangling + buffer that needs to be freed (no further action required). + + \param dev The VMU to read from. + \param fn The name of the file to read. + \param outbuf A buffer that will be allocated where the file data + will be placed. + \param outsize Storage for the size of the file, in bytes. + \return 0 on success, or <0 on failure. +*/ int vmufs_read(maple_device_t * dev, const char * fn, void ** outbuf, int * outsize); -/** Same as vmufs_read, but takes a pre-read dirent to speed things up when you - have already done a lookup. */ +/** \brief Read a file from the VMU, using a pre-read dirent. + + This function is faster to use than vmufs_read() if you already have done + the lookup, since it won't need to do that. + + \param dev The VMU to read from. + \param dirent The entry to read. + \param outbuf A buffer that will be allocated where the file data + will be placed. + \param outsize Storage for the size of the file, in bytes. + \return 0 on success, <0 on failure. +*/ int vmufs_read_dirent(maple_device_t * dev, vmu_dir_t * dirent, void ** outbuf, int * outsize); /* Flags for vmufs_write */ -#define VMUFS_OVERWRITE 1 /*< Overwrite existing files */ -#define VMUFS_VMUGAME 2 /*< This file is a VMU game */ -#define VMUFS_NOCOPY 4 /*< Set the no-copy flag */ +#define VMUFS_OVERWRITE 1 /**< \brief Overwrite existing files */ +#define VMUFS_VMUGAME 2 /**< \brief This file is a VMU game */ +#define VMUFS_NOCOPY 4 /**< \brief Set the no-copy flag */ -/** Writes a file to the VMU. If the named file already exists, then the - function checks 'flags'. If VMUFS_OVERWRITE is set, then the old - file is deleted first before the new one is written (this all happens - atomically). On partial failure, some data blocks may have been written, - but in general the card should not be damaged. Returns 0 on success, - or <0 for failure. */ +/** \brief Write a file to the VMU. + + If the named file already exists, then the function checks 'flags'. If + VMUFS_OVERWRITE is set, then the old file is deleted first before the new + one is written (this all happens atomically). On partial failure, some data + blocks may have been written, but in general the card should not be damaged. + + \param dev The VMU to write to. + \param fn The filename to write. + \param inbuf The data to write to the file. + \param insize The size of the file in bytes. + \param flags Flags for the write (i.e, VMUFS_OVERWRITE, + VMUFS_VMUGAME, VMUFS_NOCOPY). + \return 0 on success, or <0 for failure. +*/ int vmufs_write(maple_device_t * dev, const char * fn, void * inbuf, int insize, int flags); -/** Deletes a file from the VMU. Returns 0 on success, -1 if the file can't be - found, or -2 for some other error. */ +/** \brief Delete a file from the VMU. + + \retval 0 On success. + \retval -1 If the file is not found. + \retval -2 On other failure. +*/ int vmufs_delete(maple_device_t * dev, const char * fn); -/** Returns the number of user blocks free for file writing. You should check this - number before attempting to write. */ +/** \brief Return the number of user blocks free for file writing. + + You should check this number before attempting to write. + + \return The number of blocks free for writing. */ +*/ int vmufs_free_blocks(maple_device_t * dev); -/** Initialize vmufs. Must be called before anything else is useful. */ +/** \brief Initialize vmufs. + + Must be called before anything else is useful. + + \retval 0 On success (no error conditions defined). +*/ int vmufs_init(); -/** Shutdown vmufs. Must be called after everything is finished. */ +/** \brief Shutdown vmufs. + + Must be called after everything is finished. +*/ int vmufs_shutdown(); __END_DECLS This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-05-07 00:42:08
|
Revision: 710 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=710&view=rev Author: ljsebald Date: 2011-05-07 00:42:01 +0000 (Sat, 07 May 2011) Log Message: ----------- Add Doxygen comments to a bunch of sound-related stuff... Modified Paths: -------------- kos/kernel/arch/dreamcast/include/dc/sound/sfxmgr.h kos/kernel/arch/dreamcast/include/dc/sound/sound.h kos/kernel/arch/dreamcast/include/dc/sound/stream.h Modified: kos/kernel/arch/dreamcast/include/dc/sound/sfxmgr.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/sound/sfxmgr.h 2011-03-20 20:26:20 UTC (rev 709) +++ kos/kernel/arch/dreamcast/include/dc/sound/sfxmgr.h 2011-05-07 00:42:01 UTC (rev 710) @@ -1,10 +1,23 @@ /* KallistiOS ##version## dc/sound/sfxmgr.h - (c)2002 Dan Potter + Copyright (C) 2002 Dan Potter */ +/** \file dc/sound/sfxmgr.h + \brief Basic sound effect support. + + This file contains declarations for doing simple sound effects. This code is + only usable for simple WAV files containing either 16-bit samples (stereo or + mono) or Yamaha ADPCM (4-bits, stereo or mono). Also, all sounds played in + this manner must be at most 65534 samples in length, as this does not handle + buffer chaining or anything else complex. For more interesting stuff, you + should probably look at the sound stream stuff instead. + + \author Dan Potter +*/ + #ifndef __DC_SOUND_SFXMGR_H #define __DC_SOUND_SFXMGR_H @@ -13,40 +26,119 @@ #include <arch/types.h> -/* Sound effect handle type */ +/** \brief Sound effect handle type. + + Each loaded sound effect will be assigned one of these, which is to be used + for operations related to the effect, including playing it or unloading it. +*/ typedef uint32 sfxhnd_t; + +/** \brief Invalid sound effect handle value. + + If a sound effect cannot be loaded, this value will be returned as the error + condition. +*/ #define SFXHND_INVALID 0 -/* Load a sound effect from a WAV file and return a handle to it */ +/** \brief Load a sound effect. + + This function loads a sound effect from a WAV file and returns a handle to + it. The sound effect can be either stereo or mono, and must either be 16-bit + uncompressed PCM samples or 4-bit Yamaha ADPCM. + + \param fn The file to load. + \return A handle to the sound effect on success. On error, + SFXHND_INVALID is returned. +*/ sfxhnd_t snd_sfx_load(const char *fn); -/* Unload a single sample */ +/** \brief Unload a sound effect. + + This function unloads a previously loaded sound effect, and frees the memory + associated with it. + + \param idx A handle to the sound effect to unload. +*/ void snd_sfx_unload(sfxhnd_t idx); -/* Unload all loaded samples and free their SPU RAM */ +/** \brief Unload all loaded sound effects. + + This function unloads all previously loaded sound effect, and frees the + memory associated with them. +*/ void snd_sfx_unload_all(); -/* Play a sound effect with the given volume and panning; if the sound - effect is in stereo, the panning is ignored. Returns the used channel - ID (or the left channel, if stereo). */ +/** \brief Play a sound effect. + + This function plays a loaded sound effect with the specified volume (for + both stereo or mono) and panning values (for mono sounds only). + + \param idx The handle to the sound effect to play. + \param vol The volume to play at (between 0 and 255). + \param pan The panning value of the sound effect. 0 is all the + way to the left, 128 is center, 255 is all the way + to the right. + + \return The channel used to play the sound effect (or the + left channel in the case of a stereo sound, the + right channel will be the next one) on success, or + -1 on failure. +*/ int snd_sfx_play(sfxhnd_t idx, int vol, int pan); -/* Works like snd_sfx_play, but selects a specific channel. If the sample - is stereo, the next channel will also be used. */ +/** \brief Play a sound effect on a specific channel. + + This function works similar to snd_sfx_play(), but allows you to specify the + channel to play on. No error checking is done with regard to the channel, so + be sure its safe to play on that channel before trying. + + \param chn The channel to play on (or in the case of stereo, + the left channel). + \param idx The handle to the sound effect to play. + \param vol The volume to play at (between 0 and 255). + \param pan The panning value of the sound effect. 0 is all the + way to the left, 128 is center, 255 is all the way + to the right. + + \return chn +*/ int snd_sfx_play_chn(int chn, sfxhnd_t idx, int vol, int pan); -/* Stops a single sound effect from playing. */ +/** \brief Stop a single channel of sound. + + This function stops the specified channel of sound from playing. It does no + checking to make sure that a sound effect is playing on the channel + specified, and thus can be used even if you're using the channel for some + other purpose than sound effects. + + \param chn The channel to stop. +*/ void snd_sfx_stop(int chn); -/* Stop all playing sound effects. Doesn't stop channels 0 or 1, which - are assumed to be for streaming. */ +/** \brief Stop all channels playing sound effects. + + This function stops all channels currently allocated to sound effects from + playing. It does not affect channels allocated for use by something other + than sound effects.. +*/ void snd_sfx_stop_all(); -/* Allocate a channel for non-sfx usage (e.g. streams). Returns -1 - on failure. */ +/** \brief Allocate a sound channel for use outside the sound effect system. + + This function finds and allocates a channel for use for things other than + sound effects. This is useful for, for instance, the streaming code. + + \returns The allocated channel on success, -1 on failure. +*/ int snd_sfx_chn_alloc(); -/* Free a channel for non-sfx usage. */ +/** \brief Free a previously allocated channel. + + This function frees a channel that was allocated with snd_sfx_chn_alloc(), + returning it to the pool of available channels for sound effect use. + + \param chn The channel to free. +*/ void snd_sfx_chn_free(int chn); __END_DECLS Modified: kos/kernel/arch/dreamcast/include/dc/sound/sound.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/sound/sound.h 2011-03-20 20:26:20 UTC (rev 709) +++ kos/kernel/arch/dreamcast/include/dc/sound/sound.h 2011-05-07 00:42:01 UTC (rev 710) @@ -1,10 +1,21 @@ /* KallistiOS ##version## dc/sound/sound.h - (c)2002 Dan Potter + Copyright (C) 2002 Dan Potter */ +/** \file dc/sound/sound.h + \brief Low-level sound support and memory management. + + This file contains declarations for low-level sound operations and for SPU + RAM pool memory management. Most of the time you'll be better off using the + higher-level functionality in the sound effect support or streaming support, + but this stuff can be very useful for some things. + + \author Dan Potter +*/ + #ifndef __DC_SOUND_SOUND_H #define __DC_SOUND_SOUND_H @@ -13,46 +24,118 @@ #include <arch/types.h> -/* Allocate a chunk of SPU RAM; we will return an offset into SPU RAM. */ +/** \brief Allocate memory in the SPU RAM pool + + This function acts as the memory allocator for the SPU RAM pool. It acts + much like one would expect a malloc() function to act, although it does not + return a pointer directly, but rather an offset in SPU RAM. + + \param size The amount of memory to allocate, in bytes. + \return The location of the start of the block on success, + or 0 on failure. +*/ uint32 snd_mem_malloc(size_t size); -/* Free a previously allocated chunk of memory */ +/** \brief Free a block of allocated memory in the SPU RAM pool. + + This function frees memory previously allocated with snd_mem_malloc(). + + \param addr The location of the start of the block to free. +*/ void snd_mem_free(uint32 addr); -/* Return the number of bytes available in the largest free chunk */ +/** \brief Get the size of the largest allocateable block in the SPU RAM pool. + + This function returns the largest size that can be currently passed to + snd_mem_malloc() and expected to not return failure. There may be more + memory available in the pool, especially if multiple blocks have been + allocated and freed, but calls to snd_mem_malloc() for larger blocks will + return failure, since the memory is not available contiguously. + + \return The size of the largest available block of memory in + the SPU RAM pool. +*/ uint32 snd_mem_available(); -/* Reinitialize the pool with the given RAM base offset */ +/** \brief Reinitialize the SPU RAM pool. + + This function reinitializes the SPU RAM pool with the given base offset + within the memory space. There is generally not a good reason to do this in + your own code, but the functionality is there if needed. + + \param reserve The amount of memory to reserve as a base. + \retval 0 On success (no failure conditions defined). +*/ int snd_mem_init(uint32 reserve); -/* Shut down the SPU allocator */ +/** \brief Shutdown the SPU RAM allocator. + + There is generally no reason to be calling this function in your own code, + as doing so will cause problems if you try to allocate SPU memory without + calling snd_mem_init() afterwards. +*/ void snd_mem_shutdown(); -/* Initialize driver; note that this replaces the AICA program so that - if you had anything else going on, it's gone now! */ +/** \brief Initialize the sound system. + + This function reinitializes the whole sound system. It will not do anything + unless the sound system has been shut down previously or has not been + initialized yet. This will implicitly replace the program running on the + AICA's ARM processor when it actually initializes anything. The default + snd_stream_drv will be loaded if a new program is uploaded to the SPU. +*/ int snd_init(); -/* Shut everything down and free mem */ +/** \brief Shut down the sound system. + + This function shuts down the whole sound system, freeing memory and + disabling the SPU in the process. There's not generally many good reasons + for doing this in your own code. +*/ void snd_shutdown(); -/* Queue up a request to the SH4->AICA queue; size is in uint32's */ +/** \brief Copy a request packet to the AICA queue. + + This function is to put in a low-level request using the built-in streaming + sound driver. + + \param packet The packet of data to copy. + \param size The size of the packet, in 32-bit increments. + \retval 0 On success (no error conditions defined). +*/ int snd_sh4_to_aica(void *packet, uint32 size); -/* Start processing requests in the queue */ +/** \brief Begin processing AICA queue requests. + + This function begins processing of any queued requests in the AICA queue. +*/ void snd_sh4_to_aica_start(); -/* Stop processing requests in the queue */ +/** \brief Stop processing AICA queue requests. + + This function stops the processing of any queued requests in the AICA queue. +*/ void snd_sh4_to_aica_stop(); -/* Transfer one packet of data from the AICA->SH4 queue. Expects to - find AICA_CMD_MAX_SIZE dwords of space available. Returns -1 - if failure, 0 for no packets available, 1 otherwise. Failure - might mean a permanent failure since the queue is probably out of sync. */ +/** \brief Transfer a packet of data from the AICA's SH4 queue. + + This function is used to retrieve a packet of data from the AICA back to the + SH4. The buffer passed in should at least contain 1024 bytes of space to + make sure any packet can fit. + + \param packetout The buffer to store the retrieved packet in. + \retval -1 On failure. Failure probably indicates the queue has + been corrupted, and thus should be reinitialized. + \retval 0 If no packets are available. + \retval 1 On successful copy of one packet. +*/ int snd_aica_to_sh4(void *packetout); -/* Poll for responses from the AICA. We assume here that we're not - running in an interrupt handler (thread perhaps, of whoever - is using us). */ +/** \brief Poll for a response from the AICA. + + This function waits for the AICA to respond to a previously sent request. + This function is not safe to call in an IRQ, as it does implicitly wait. +*/ void snd_poll_resp(); __END_DECLS Modified: kos/kernel/arch/dreamcast/include/dc/sound/stream.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/sound/stream.h 2011-03-20 20:26:20 UTC (rev 709) +++ kos/kernel/arch/dreamcast/include/dc/sound/stream.h 2011-05-07 00:42:01 UTC (rev 710) @@ -1,10 +1,21 @@ /* KallistiOS ##version## dc/sound/stream.h - Copyright (C)2002,2004 Dan Potter + Copyright (C) 2002, 2004 Dan Potter */ +/** \file dc/sound/stream.h + \brief Sound streaming support. + + This file contains declarations for doing streams of sound. This underlies + pretty much any decoded sounds you might use, including the Ogg Vorbis + libraries. Note that this does not actually handle decoding, so you'll have + to worry about that yourself (or use something in kos-ports). + + \author Dan Potter +*/ + #ifndef __DC_SOUND_STREAM_H #define __DC_SOUND_STREAM_H @@ -13,20 +24,48 @@ #include <arch/types.h> -/* The maximum number of streams which can be allocated at once */ +/** \brief The maximum number of streams that can be allocated at once. */ #define SND_STREAM_MAX 4 -/* The maximum buffer size for a stream */ +/** \brief The maximum buffer size for a stream. */ #define SND_STREAM_BUFFER_MAX 0x10000 -/* A stream handle */ +/** \brief Stream handle type. + + Each stream will be assigned a handle, which will be of this type. Further + operations on the stream will use the handle to identify which stream is + being referred to. +*/ typedef int snd_stream_hnd_t; -/* An invalid stream handle */ +/** \brief Invalid stream handle. + + If a stream cannot be allocated, this will be returned. +*/ #define SND_STREAM_INVALID -1 -/* Set "get data" callback */ -typedef void* (*snd_stream_callback_t)(snd_stream_hnd_t hnd, int smp_req, int * smp_recv); +/** \brief Stream get data callback type. + + Functions for providing stream data will be of this type, and can be + registered with snd_stream_set_callback(). + + \param hnd The stream handle being referred to. + \param smp_req The number of samples requested. + \param smp_recv Used to return the number of samples available. + \return A pointer to the buffer of samples. If stereo, the + samples should be interleaved. +*/ +typedef void *(*snd_stream_callback_t)(snd_stream_hnd_t hnd, int smp_req, + int *smp_recv); + +/** \brief Set the callback for a given stream. + + This function sets the get data callback function for a given stream, + overwriting any old callback that may have been in place. + + \param hnd The stream handle for the callback. + \param cb A pointer to the callback function. +*/ void snd_stream_set_callback(snd_stream_hnd_t hnd, snd_stream_callback_t cb); /* Add an effect filter to the sound stream chain. When the stream @@ -35,47 +74,182 @@ filter chain, which can modify the buffer and the amount of data available as well. Filters persist across multiple calls to _init() but will be emptied by _shutdown(). */ -typedef void (*snd_stream_filter_t)(snd_stream_hnd_t hnd, void * obj, int hz, int channels, void **buffer, int *samplecnt); -void snd_stream_filter_add(snd_stream_hnd_t hnd, snd_stream_filter_t filtfunc, void * obj); -/* Remove a filter added with the above function */ -void snd_stream_filter_remove(snd_stream_hnd_t hnd, snd_stream_filter_t filtfunc, void * obj); +/** \brief Stream filter callback type. -/* Prefill buffers -- do this before calling start() */ + Functions providing filters over the stream data will be of this type, and + can be set with snd_stream_filter_add(). + + \param hnd The stream being referred to. + \param obj Filter user data. + \param hz The frequency of the sound data. + \param channels The number of channels in the sound data. + \param buffer A pointer to the buffer to process. This is before + any stereo separation is done. Can be changed by the + filter, if appropriate. + \param samplecnt A pointer to the number of samples. This can be + modified by the filter, if appropriate. +*/ +typedef void (*snd_stream_filter_t)(snd_stream_hnd_t hnd, void *obj, int hz, + int channels, void **buffer, + int *samplecnt); + +/** \brief Add a filter to the specified stream. + + This function adds a filter to the specified stream. The filter will be + called on each block of data input to the stream from then forward. + + \param hnd The stream to add the filter to. + \param filtfunc A pointer to the filter function. + \param obj Filter function user data. +*/ +void snd_stream_filter_add(snd_stream_hnd_t hnd, snd_stream_filter_t filtfunc, + void *obj); + +/** \brief Remove a filter from the specified stream. + + This function removes a filter that was previously added to the specified + stream. + + \param hnd The stream to remove the filter from. + \param filtfunc A pointer to the filter function to remove. + \param obj The filter function's user data. Must be the same as + what was passed as obj to snd_stream_filter_add(). +*/ +void snd_stream_filter_remove(snd_stream_hnd_t hnd, + snd_stream_filter_t filtfunc, void *obj); + +/** \brief Prefill the stream buffers. + + This function prefills the stream buffers before starting it. This is + implicitly called by snd_stream_start(), so there's probably no good reason + to call this yourself. + + \param hnd The stream to prefill buffers on. +*/ void snd_stream_prefill(snd_stream_hnd_t hnd); -/* Initialize stream system */ +/** \brief Initialize the stream system. + + This function initializes the sound stream system and allocates memory for + it as needed. Note, this is not done by the default init, so if you're using + the streaming support and not using something like the kos-ports Ogg Vorbis + library, you'll need to call this yourself. This will implicitly call + snd_init(), so it will potentially overwrite anything going on the AICA. + + \retval -1 On failure. + \retval 0 On success. +*/ int snd_stream_init(); -/* Shut everything down and free mem */ +/** \brief Shut down the stream system. + + This function shuts down the stream system and frees the memory associated + with it. This does not call snd_shutdown(). +*/ void snd_stream_shutdown(); -/* Allocate and init a stream channel */ +/** \brief Allocate a stream. + + This function allocates a stream and sets its parameters. + + \param cb The get data callback for the stream. + \param bufsize The size of the buffer for the stream. + \return A handle to the new stream on success, + SND_STREAM_INVALID on failure. +*/ snd_stream_hnd_t snd_stream_alloc(snd_stream_callback_t cb, int bufsize); -/* Re-init a stream channel */ +/** \brief Reinitialize a stream. + + This function reinitializes a stream, resetting its callback function. + + \param hnd The stream handle to reinit. + \param cb The new get data callback for the stream. + \return hnd +*/ int snd_stream_reinit(snd_stream_hnd_t hnd, snd_stream_callback_t cb); -/* Destroy a stream channel */ +/** \brief Destroy a stream. + + This function destroys a previously created stream, freeing all memory + associated with it. + + \param hnd The stream to clean up. +*/ void snd_stream_destroy(snd_stream_hnd_t hnd); -/* Enable / disable stream queueing */ +/** \brief Enable queueing on a stream. + + This function enables queueing on the specified stream. This will make it so + that you must call snd_stream_queue_go() to actually start the stream, after + scheduling the start. This is useful for getting something ready but not + firing it right away. + + \param hnd The stream to enable queueing on. +*/ void snd_stream_queue_enable(snd_stream_hnd_t hnd); + +/** \brief Disable queueing on a stream. + + This function disables queueing on the specified stream. This does not imply + that a previously queued start on the stream will be fired if queueing was + enabled before. + + \param hnd The stream to disable queueing on. +*/ void snd_stream_queue_disable(snd_stream_hnd_t hnd); -/* Actually make it go (in queued mode) */ +/** \brief Start a stream after queueing the request. + + This function makes the stream start once a start request has been queued, + if queueing mode is enabled on the stream. + + \param hnd The stream to start the queue on. +*/ void snd_stream_queue_go(snd_stream_hnd_t hnd); -/* Start streaming */ +/** \brief Start a stream. + + This function starts processing the given stream, prefilling the buffers as + necessary. In queueing mode, this will not start playback. + + \param hnd The stream to start. + \param freq The frequency of the sound. + \param st 1 if the sound is stereo, 0 if mono. +*/ void snd_stream_start(snd_stream_hnd_t hnd, uint32 freq, int st); -/* Stop streaming */ +/** \brief Stop a stream. + + This function stops a stream, stopping any sound playing from it. This will + happen immediately, regardless of whether queueing is enabled or not. + + \param hnd The stream to stop. +*/ void snd_stream_stop(snd_stream_hnd_t hnd); -/* Poll streamer to load more data if neccessary */ +/** \brief Poll a stream. + + This function polls the specified stream to load more data if necessary. If + using the streaming support, you must call this function periodically (most + likely in a thread), or you won't get any sound output. + + \param hnd The stream to poll. + \retval -3 If NULL was returned from the callback. + \retval -1 If no callback is set, or if the state has been + corrupted. + \retval 0 On success. +*/ int snd_stream_poll(snd_stream_hnd_t hnd); -/* Set the volume on the streaming channels */ +/** \brief Set the volume on the stream. + + This function sets the volume of the specified stream. + + \param hnd The stream to set volume on. + \param vol The volume to set. Valid values are 0-255. +*/ void snd_stream_volume(snd_stream_hnd_t hnd, int vol); __END_DECLS This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-03-20 20:26:26
|
Revision: 709 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=709&view=rev Author: ljsebald Date: 2011-03-20 20:26:20 +0000 (Sun, 20 Mar 2011) Log Message: ----------- Copy IPv6 addresses passed into inet_ntop into an internal buffer to deal with any sort of alignment issues... Modified Paths: -------------- kos/kernel/libc/koslib/inet_ntop.c kos/kernel/net/net_icmp6.c Modified: kos/kernel/libc/koslib/inet_ntop.c =================================================================== --- kos/kernel/libc/koslib/inet_ntop.c 2011-03-20 20:22:01 UTC (rev 708) +++ kos/kernel/libc/koslib/inet_ntop.c 2011-03-20 20:26:20 UTC (rev 709) @@ -1,12 +1,13 @@ /* KallistiOS ##version## inet_ntop.c - Copyright (C) 2007, 2010 Lawrence Sebald + Copyright (C) 2007, 2010, 2011 Lawrence Sebald */ #include <arpa/inet.h> #include <errno.h> +#include <string.h> static const char *inet_ntop4(const void *src, char *dst, socklen_t size) { char tmp[3]; @@ -54,21 +55,24 @@ } static const char *inet_ntop6(const void *src, char *dst, socklen_t size) { - struct in6_addr *addr = (struct in6_addr *)src; int tmp[8] = { 0 }; int runstart = -1, maxzero = 0, dcs = -1, i; char tmpstr[4]; char *ch = tmpstr, *ch2 = dst; int part; + struct in6_addr addr; + /* Copy the address, just in case the original was misaligned */ + memcpy(&addr, src, sizeof(struct in6_addr)); + /* Handle the special cases of IPv4 Mapped and Compatibility addresses */ - if(IN6_IS_ADDR_V4MAPPED(addr)) { + if(IN6_IS_ADDR_V4MAPPED(&addr)) { if(size > 7) { dst[0] = dst[1] = dst[6] = ':'; dst[2] = dst[3] = dst[4] = dst[5] = 'f'; /* Parse the IPv4 address at the end */ - if(!inet_ntop4(&addr->__s6_addr.__s6_addr32[3], dst + 7, size - 7)) + if(!inet_ntop4(&addr.__s6_addr.__s6_addr32[3], dst + 7, size - 7)) goto err; return dst; @@ -77,12 +81,12 @@ goto err; } } - else if(IN6_IS_ADDR_V4COMPAT(addr)) { + else if(IN6_IS_ADDR_V4COMPAT(&addr)) { if(size > 2) { dst[0] = dst[1] = ':'; /* Parse the IPv4 address at the end */ - if(!inet_ntop4(&addr->__s6_addr.__s6_addr32[3], dst + 2, size - 2)) + if(!inet_ntop4(&addr.__s6_addr.__s6_addr32[3], dst + 2, size - 2)) goto err; return dst; @@ -94,7 +98,7 @@ /* Figure out if we have any use for double colons in the address or not */ for(i = 0; i < 8; ++i) { - if(addr->__s6_addr.__s6_addr16[i] == 0) { + if(addr.__s6_addr.__s6_addr16[i] == 0) { if(runstart != -1) { ++tmp[runstart]; } @@ -141,7 +145,7 @@ } } else { - part = ntohs(addr->__s6_addr.__s6_addr16[i]); + part = ntohs(addr.__s6_addr.__s6_addr16[i]); do { *ch = (char)(part & 0x0f) + '0'; Modified: kos/kernel/net/net_icmp6.c =================================================================== --- kos/kernel/net/net_icmp6.c 2011-03-20 20:22:01 UTC (rev 708) +++ kos/kernel/net/net_icmp6.c 2011-03-20 20:26:20 UTC (rev 709) @@ -40,11 +40,8 @@ uint64 delta_us, uint8 hlim, const uint8 *data, int data_sz) { char ipstr[INET6_ADDRSTRLEN]; - struct in6_addr a; - /* Copy the address to prevent unaligned accesses... */ - memcpy(&a, ip, sizeof(struct in6_addr)); - inet_ntop(AF_INET6, &a, ipstr, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, ip, ipstr, INET6_ADDRSTRLEN); if(delta_us != (uint64)-1) { printf("%d bytes from %s, icmp_seq=%d hlim=%d time=%.3f ms\n", data_sz, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-03-20 20:22:08
|
Revision: 708 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=708&view=rev Author: ljsebald Date: 2011-03-20 20:22:01 +0000 (Sun, 20 Mar 2011) Log Message: ----------- Add in pthread-mapped TLS functionality. Modified Paths: -------------- kos/include/kos/once.h kos/include/sys/sched.h kos/kernel/libc/pthreads/pthread_tls.c kos/kernel/thread/once.c kos/kernel/thread/thread.c Modified: kos/include/kos/once.h =================================================================== --- kos/include/kos/once.h 2011-03-12 22:14:07 UTC (rev 707) +++ kos/include/kos/once.h 2011-03-20 20:22:01 UTC (rev 708) @@ -29,10 +29,13 @@ This object type should always be initialized with the KTHREAD_ONCE_INIT macro. */ -typedef int kthread_once_t; +typedef struct { + int initialized; + int run; +} kthread_once_t; /** \brief Initializer for a kthread_once_t object. */ -#define KTHREAD_ONCE_INIT 0 +#define KTHREAD_ONCE_INIT { 1, 0 } /** \brief Run a function once. Modified: kos/include/sys/sched.h =================================================================== --- kos/include/sys/sched.h 2011-03-12 22:14:07 UTC (rev 707) +++ kos/include/sys/sched.h 2011-03-20 20:22:01 UTC (rev 708) @@ -23,6 +23,8 @@ #include <kos/sem.h> #include <kos/cond.h> #include <kos/mutex.h> +#include <kos/tls.h> +#include <kos/once.h> // Missing structs we don't care about in this impl. typedef struct { @@ -37,21 +39,15 @@ // Empty } pthread_attr_t; -typedef struct { - int initialized; - int run; -} pthread_once_t; - -typedef struct { - // Empty -} pthread_key_t; - // Map over KOS types. The mutex/condvar maps have to be pointers // because we allow _INIT #defines to work. typedef kthread_t * pthread_t; typedef mutex_t * pthread_mutex_t; typedef condvar_t * pthread_cond_t; +// These, on the other hand, map right over. +typedef kthread_once_t pthread_once_t; +typedef kthread_key_t pthread_key_t; __END_DECLS Modified: kos/kernel/libc/pthreads/pthread_tls.c =================================================================== --- kos/kernel/libc/pthreads/pthread_tls.c 2011-03-12 22:14:07 UTC (rev 707) +++ kos/kernel/libc/pthreads/pthread_tls.c 2011-03-20 20:22:01 UTC (rev 708) @@ -3,27 +3,27 @@ /* Dynamic Package Initialization */ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { - return EINVAL; + return kthread_once(once_control, init_routine); } /* Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163 */ int pthread_key_create(pthread_key_t *key, void (*destructor)( void * )) { - return EINVAL; + return kthread_key_create(key, destructor); } /* Thread-Specific Data Management, P1003.1c/Draft 10, p. 165 */ int pthread_setspecific(pthread_key_t key, const void *value) { - return EINVAL; + return kthread_setspecific(key, value); } void * pthread_getspecific(pthread_key_t key) { - return NULL; + return kthread_getspecific(key); } /* Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167 */ int pthread_key_delete(pthread_key_t key) { - return EINVAL; + return kthread_key_delete(key); } Modified: kos/kernel/thread/once.c =================================================================== --- kos/kernel/thread/once.c 2011-03-12 22:14:07 UTC (rev 707) +++ kos/kernel/thread/once.c 2011-03-20 20:22:01 UTC (rev 708) @@ -24,10 +24,10 @@ /* Create the lock if needed. */ old = irq_disable(); - if(!lock) { + if(!lock) { lock = rlock_create(); - if(!lock) { + if(!lock) { return -1; } } @@ -35,19 +35,19 @@ irq_restore(old); /* Lock the lock. */ - if(rlock_lock(lock) == -1) { + if(rlock_lock(lock) == -1) { return -1; } /* If the function has already been run, unlock the lock and return. */ - if(*once_control) { + if(once_control->run) { rlock_unlock(lock); return 0; } /* Run the function, set the control, and unlock the lock. */ init_routine(); - *once_control = 1; + once_control->run = 1; rlock_unlock(lock); return 0; Modified: kos/kernel/thread/thread.c =================================================================== --- kos/kernel/thread/thread.c 2011-03-12 22:14:07 UTC (rev 707) +++ kos/kernel/thread/thread.c 2011-03-20 20:22:01 UTC (rev 708) @@ -668,7 +668,7 @@ old = irq_disable(); /* Search the thread list and make sure that this thread hasn't - already died and been deallocated. */ + already died and been deallocated. */ LIST_FOREACH(t, &thd_list, t_list) { if (t == thd) break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-03-12 22:14:13
|
Revision: 707 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=707&view=rev Author: ljsebald Date: 2011-03-12 22:14:07 +0000 (Sat, 12 Mar 2011) Log Message: ----------- Do the same for IPv4 pings. Modified Paths: -------------- kos/kernel/net/net_icmp.c kos/kernel/net/net_icmp6.c Modified: kos/kernel/net/net_icmp.c =================================================================== --- kos/kernel/net/net_icmp.c 2011-03-12 21:42:28 UTC (rev 706) +++ kos/kernel/net/net_icmp.c 2011-03-12 22:14:07 UTC (rev 707) @@ -3,7 +3,7 @@ kernel/net/net_icmp.c Copyright (C) 2002 Dan Potter - Copyright (C) 2005, 2006, 2007, 2009, 2010 Lawrence Sebald + Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011 Lawrence Sebald */ @@ -51,24 +51,17 @@ Any other numbers not listed in the earlier list... */ -struct ping_pkt { - LIST_ENTRY(ping_pkt) pkt_list; - uint8 ip[4]; - uint8 *data; - int data_sz; - uint16 icmp_seq; - uint64 usec; -}; - -LIST_HEAD(ping_pkt_list, ping_pkt); - -static struct ping_pkt_list pings = LIST_HEAD_INITIALIZER(0); - static void icmp_default_echo_cb(const uint8 *ip, uint16 seq, uint64 delta_us, uint8 ttl, const uint8* data, int data_sz) { - printf("%d bytes from %d.%d.%d.%d: icmp_seq=%d ttl=%d time=%.3f ms\n", - data_sz, ip[0], ip[1], ip[2], ip[3], seq, ttl, - delta_us / 1000.0); + if(delta_us != (uint64)-1) { + printf("%d bytes from %d.%d.%d.%d: icmp_seq=%d ttl=%d time=%.3f ms\n", + data_sz, ip[0], ip[1], ip[2], ip[3], seq, ttl, + delta_us / 1000.0); + } + else { + printf("%d bytes from %d.%d.%d.%d: icmp_seq=%d ttl=%d\n", data_sz, + ip[0], ip[1], ip[2], ip[3], seq, ttl); + } } /* The default echo (ping) callback */ @@ -77,25 +70,22 @@ /* Handle Echo Reply (ICMP type 0) packets */ static void net_icmp_input_0(netif_t *src, ip_hdr_t *ip, icmp_hdr_t *icmp, const uint8 *d, int s) { - uint64 tmr; - struct ping_pkt *ping; + uint64 tmr, otmr; uint16 seq; tmr = timer_us_gettime64(); seq = (d[7] | (d[6] << 8)); - LIST_FOREACH(ping, &pings, pkt_list) { - if(ping->icmp_seq == seq) { - net_icmp_echo_cb((uint8 *)&ip->src, seq, - tmr - ping->usec, ip->ttl, d, s); - - LIST_REMOVE(ping, pkt_list); - free(ping->data); - free(ping); - - return; - } + /* Read back the time if we have it */ + if(s >= sizeof(icmp_hdr_t) + 8) { + otmr = ((uint64)d[8] << 56) | ((uint64)d[9] << 48) | + ((uint64)d[10] << 40) | ((uint64)d[11] << 32) | + (d[12] << 24) | (d[13] << 16) | (d[14] << 8) | (d[15]); + net_icmp_echo_cb((uint8 *)&ip->src, seq, tmr - otmr, ip->ttl, d, s); } + else { + net_icmp_echo_cb((uint8 *)&ip->src, seq, -1, ip->ttl, d, s); + } } /* Handle Echo (ICMP type 8) packets */ @@ -161,10 +151,11 @@ int net_icmp_send_echo(netif_t *net, const uint8 ipaddr[4], uint16 ident, uint16 seq, const uint8 *data, int size) { icmp_hdr_t *icmp; - struct ping_pkt *newping; int r = -1; - uint8 databuf[sizeof(icmp_hdr_t) + size]; + uint16 sz = sizeof(icmp_hdr_t) + size + 8; + uint8 databuf[sz]; uint32 src; + uint64 t; icmp = (icmp_hdr_t *)databuf; @@ -174,10 +165,22 @@ icmp->checksum = 0; icmp->misc.m16[0] = htons(ident); icmp->misc.m16[1] = htons(seq); - memcpy(databuf + sizeof(icmp_hdr_t), data, size); + memcpy(databuf + sizeof(icmp_hdr_t) + 8, data, size); + /* Put the time in now, at the latest possible time (since we have to + calculate the checksum over it) */ + t = timer_us_gettime64(); + databuf[sizeof(icmp_hdr_t) + 0] = t >> 56; + databuf[sizeof(icmp_hdr_t) + 1] = t >> 48; + databuf[sizeof(icmp_hdr_t) + 2] = t >> 40; + databuf[sizeof(icmp_hdr_t) + 3] = t >> 32; + databuf[sizeof(icmp_hdr_t) + 4] = t >> 24; + databuf[sizeof(icmp_hdr_t) + 5] = t >> 16; + databuf[sizeof(icmp_hdr_t) + 6] = t >> 8; + databuf[sizeof(icmp_hdr_t) + 7] = t >> 0; + /* Compute the ICMP Checksum */ - icmp->checksum = net_ipv4_checksum(databuf, sizeof(icmp_hdr_t) + size, 0); + icmp->checksum = net_ipv4_checksum(databuf, sz, 0); /* If we're sending to the loopback, set that as our source too. */ if(ipaddr[0] == 127) { @@ -187,18 +190,9 @@ src = net_ipv4_address(net->ip_addr); } - newping = (struct ping_pkt*) malloc(sizeof(struct ping_pkt)); - newping->data = (uint8 *)malloc(size); - newping->data_sz = size; - newping->icmp_seq = seq; - memcpy(newping->data, data, size); - memcpy(newping->ip, ipaddr, 4); - LIST_INSERT_HEAD(&pings, newping, pkt_list); + r = net_ipv4_send(net, databuf, sz, seq, 255, 1, htonl(src), + htonl(net_ipv4_address(ipaddr))); - newping->usec = timer_us_gettime64(); - r = net_ipv4_send(net, databuf, sizeof(icmp_hdr_t) + size, seq, 255, 1, - htonl(src), htonl(net_ipv4_address(ipaddr))); - return r; } Modified: kos/kernel/net/net_icmp6.c =================================================================== --- kos/kernel/net/net_icmp6.c 2011-03-12 21:42:28 UTC (rev 706) +++ kos/kernel/net/net_icmp6.c 2011-03-12 22:14:07 UTC (rev 707) @@ -1,7 +1,7 @@ /* KallistiOS ##version## kernel/net/net_icmp6.c - Copyright (C) 2010 Lawrence Sebald + Copyright (C) 2010, 2011 Lawrence Sebald */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-03-12 21:42:34
|
Revision: 706 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=706&view=rev Author: ljsebald Date: 2011-03-12 21:42:28 +0000 (Sat, 12 Mar 2011) Log Message: ----------- No real need to keep state about pings... Modified Paths: -------------- kos/kernel/net/net_icmp6.c Modified: kos/kernel/net/net_icmp6.c =================================================================== --- kos/kernel/net/net_icmp6.c 2011-03-11 22:56:59 UTC (rev 705) +++ kos/kernel/net/net_icmp6.c 2011-03-12 21:42:28 UTC (rev 706) @@ -36,27 +36,24 @@ Any other numbers not listed in the first list... */ -struct ping_pkt { - LIST_ENTRY(ping_pkt) pkt_list; - struct in6_addr ip; - uint8 *data; - int data_sz; - uint16 icmp_seq; - uint64 usec; -}; - -LIST_HEAD(ping_pkt_list, ping_pkt); - -static struct ping_pkt_list pings = LIST_HEAD_INITIALIZER(0); - static void icmp6_default_echo_cb(const struct in6_addr *ip, uint16 seq, uint64 delta_us, uint8 hlim, const uint8 *data, int data_sz) { char ipstr[INET6_ADDRSTRLEN]; + struct in6_addr a; - printf("%d bytes from %s, icmp_seq=%d hlim=%d time=%.3f ms\n", data_sz, - inet_ntop(AF_INET6, ip, ipstr, INET6_ADDRSTRLEN), seq, hlim, - delta_us / 1000.0); + /* Copy the address to prevent unaligned accesses... */ + memcpy(&a, ip, sizeof(struct in6_addr)); + inet_ntop(AF_INET6, &a, ipstr, INET6_ADDRSTRLEN); + + if(delta_us != (uint64)-1) { + printf("%d bytes from %s, icmp_seq=%d hlim=%d time=%.3f ms\n", data_sz, + ipstr, seq, hlim, delta_us / 1000.0); + } + else { + printf("%d bytes from %s, icmp_seq=%d hlim=%d\n", data_sz, ipstr, seq, + hlim); + } } /* The default echo (ping6) callback */ @@ -65,27 +62,22 @@ /* Handle Echo Reply (ICMPv6 type 129) packets */ static void net_icmp6_input_129(netif_t *net, ipv6_hdr_t *ip, icmp6_hdr_t *icmp, const uint8 *d, int s) { - uint64 tmr; - struct ping_pkt *ping; + uint64 tmr, otmr = 0; uint16 seq; tmr = timer_us_gettime64(); seq = (d[7] | (d[6] << 8)); - LIST_FOREACH(ping, &pings, pkt_list) { - if(ping->icmp_seq == seq) { - if(net_icmp6_echo_cb) { - net_icmp6_echo_cb(&ping->ip, seq, tmr - ping->usec, - ip->hop_limit, d, s); - } - - LIST_REMOVE(ping, pkt_list); - free(ping->data); - free(ping); - - return; - } + /* Read back the time if we have it */ + if(s >= sizeof(icmp6_echo_hdr_t) + 8) { + otmr = ((uint64)d[8] << 56) | ((uint64)d[9] << 48) | + ((uint64)d[10] << 40) | ((uint64)d[11] << 32) | + (d[12] << 24) | (d[13] << 16) | (d[14] << 8) | (d[15]); + net_icmp6_echo_cb(&ip->src_addr, seq, tmr - otmr, ip->hop_limit, d, s); } + else { + net_icmp6_echo_cb(&ip->src_addr, seq, -1, ip->hop_limit, d, s); + } } /* Handle Echo (ICMPv6 type 128) packets */ @@ -464,10 +456,11 @@ int net_icmp6_send_echo(netif_t *net, const struct in6_addr *dst, uint16 ident, uint16 seq, const uint8 *data, int size) { icmp6_echo_hdr_t *echo; - struct ping_pkt *newping; - uint8 databuf[sizeof(icmp6_hdr_t) + size + 4]; + uint8 databuf[sizeof(icmp6_echo_hdr_t) + size + 8]; struct in6_addr src; uint16 cs; + uint64 t; + uint16 sz = sizeof(icmp6_echo_hdr_t) + size + 8; if(!net) { if(!(net = net_default_dev)) { @@ -497,25 +490,25 @@ echo->checksum = 0; echo->ident = htons(ident); echo->seq = htons(seq); - memcpy(databuf + sizeof(icmp6_echo_hdr_t), data, size); + memcpy(databuf + sizeof(icmp6_echo_hdr_t) + 8, data, size); + /* Put the time in now, at the latest possible time (since we have to + calculate the checksum over it) */ + t = timer_us_gettime64(); + databuf[sizeof(icmp6_echo_hdr_t) + 0] = t >> 56; + databuf[sizeof(icmp6_echo_hdr_t) + 1] = t >> 48; + databuf[sizeof(icmp6_echo_hdr_t) + 2] = t >> 40; + databuf[sizeof(icmp6_echo_hdr_t) + 3] = t >> 32; + databuf[sizeof(icmp6_echo_hdr_t) + 4] = t >> 24; + databuf[sizeof(icmp6_echo_hdr_t) + 5] = t >> 16; + databuf[sizeof(icmp6_echo_hdr_t) + 6] = t >> 8; + databuf[sizeof(icmp6_echo_hdr_t) + 7] = t >> 0; + /* Compute the ICMP Checksum */ - cs = net_ipv6_checksum_pseudo(&src, dst, sizeof(icmp6_echo_hdr_t) + size, - IPV6_HDR_ICMP); - echo->checksum = net_ipv4_checksum(databuf, sizeof(icmp6_echo_hdr_t) + size, - cs); + cs = net_ipv6_checksum_pseudo(&src, dst, sz, IPV6_HDR_ICMP); + echo->checksum = net_ipv4_checksum(databuf, sz, cs); - newping = (struct ping_pkt *) malloc(sizeof(struct ping_pkt)); - newping->data = (uint8 *)malloc(size); - newping->data_sz = size; - newping->icmp_seq = seq; - memcpy(newping->data, data, size); - newping->ip = *dst; - LIST_INSERT_HEAD(&pings, newping, pkt_list); - - newping->usec = timer_us_gettime64(); - return net_ipv6_send(net, databuf, sizeof(icmp6_echo_hdr_t) + size, 0, - IPV6_HDR_ICMP, &src, dst); + return net_ipv6_send(net, databuf, sz, 0, IPV6_HDR_ICMP, &src, dst); } /* Send a Neighbor Solicitation packet on the specified device */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-03-11 22:57:06
|
Revision: 705 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=705&view=rev Author: ljsebald Date: 2011-03-11 22:56:59 +0000 (Fri, 11 Mar 2011) Log Message: ----------- Colorized biosfont code, based on that by Chilly Willy. Its not exactly the same as his version, but it is a bit more general this way. Modified Paths: -------------- kos/kernel/arch/dreamcast/hardware/biosfont.c kos/kernel/arch/dreamcast/include/dc/biosfont.h Modified: kos/kernel/arch/dreamcast/hardware/biosfont.c =================================================================== --- kos/kernel/arch/dreamcast/hardware/biosfont.c 2011-03-02 21:43:06 UTC (rev 704) +++ kos/kernel/arch/dreamcast/hardware/biosfont.c 2011-03-11 22:56:59 UTC (rev 705) @@ -21,11 +21,20 @@ All the Japanese code is by Kazuaki Matsumoto. +Foreground/background color switching based on code by Chilly Willy. + */ /* Our current conversion mode */ -int bfont_code_mode = BFONT_CODE_ISO8859_1; +static int bfont_code_mode = BFONT_CODE_ISO8859_1; +/* Current colors/pixel format. Default to white foreground, black background + and 16-bit drawing, so the default behavior doesn't change from what it has + been forever. */ +static uint32 bfont_fgcolor = 0xFFFFFFFF; +static uint32 bfont_bgcolor = 0x00000000; +static int bfont_32bit = 0; + /* Select an encoding for Japanese (or disable) */ void bfont_set_encoding(int enc) { if (enc < BFONT_CODE_ISO8859_1 || enc > BFONT_CODE_SJIS) { @@ -34,6 +43,27 @@ bfont_code_mode = enc; } +/* Set the foreground color and return the old color */ +uint32 bfont_set_foreground_color(uint32 c) { + uint32 rv = bfont_fgcolor; + bfont_fgcolor = c; + return rv; +} + +/* Set the background color and return the old color */ +uint32 bfont_set_background_color(uint32 c) { + uint32 rv = bfont_bgcolor; + bfont_bgcolor = c; + return rv; +} + +/* Set the font to draw in 32 or 16 bit mode */ +int bfont_set_32bit_mode(int on) { + int rv = bfont_32bit; + bfont_32bit = !!on; + return rv; +} + /* A little assembly that grabs the font address */ extern uint8* get_font_address(); asm( @@ -132,7 +162,7 @@ } /* Draw half-width kana */ -void bfont_draw_thin(uint16 *buffer, int bufwidth, int opaque, int c, int iskana) { +void bfont_draw_thin(void *b, int bufwidth, int opaque, int c, int iskana) { uint8 *ch; uint16 word; int x, y; @@ -142,77 +172,152 @@ else ch = bfont_find_char(c); - for (y=0; y<24; ) { - /* Do the first row */ - word = (((uint16)ch[0]) << 4) | ((ch[1] >> 4) & 0x0f); - for (x=0; x<12; x++) { - if (word & (0x0800 >> x)) - *buffer = 0xffff; - else { - if (opaque) - *buffer = 0x0000; + if (!bfont_32bit) { + uint16 *buffer = (uint16 *)b; + + for (y=0; y<24; ) { + /* Do the first row */ + word = (((uint16)ch[0]) << 4) | ((ch[1] >> 4) & 0x0f); + for (x=0; x<12; x++) { + if (word & (0x0800 >> x)) + *buffer = bfont_fgcolor; + else { + if (opaque) + *buffer = bfont_bgcolor; + } + buffer++; } - buffer++; + buffer += bufwidth - 12; + y++; + + /* Do the second row */ + word = ( (((uint16)ch[1]) << 8) & 0xf00 ) | ch[2]; + for (x=0; x<12; x++) { + if (word & (0x0800 >> x)) + *buffer = bfont_fgcolor; + else { + if (opaque) + *buffer = bfont_bgcolor; + } + buffer++; + } + buffer += bufwidth - 12; + y++; + + ch += 3; } - buffer += bufwidth - 12; - y++; + } + else { + uint32 *buffer = (uint32 *)b; - /* Do the second row */ - word = ( (((uint16)ch[1]) << 8) & 0xf00 ) | ch[2]; - for (x=0; x<12; x++) { - if (word & (0x0800 >> x)) - *buffer = 0xffff; - else { - if (opaque) - *buffer = 0x0000; + for (y=0; y<24; ) { + /* Do the first row */ + word = (((uint16)ch[0]) << 4) | ((ch[1] >> 4) & 0x0f); + for (x=0; x<12; x++) { + if (word & (0x0800 >> x)) + *buffer = bfont_fgcolor; + else { + if (opaque) + *buffer = bfont_bgcolor; + } + buffer++; } - buffer++; + buffer += bufwidth - 12; + y++; + + /* Do the second row */ + word = ( (((uint16)ch[1]) << 8) & 0xf00 ) | ch[2]; + for (x=0; x<12; x++) { + if (word & (0x0800 >> x)) + *buffer = bfont_fgcolor; + else { + if (opaque) + *buffer = bfont_bgcolor; + } + buffer++; + } + buffer += bufwidth - 12; + y++; + + ch += 3; } - buffer += bufwidth - 12; - y++; - - ch += 3; } } /* Compat function */ -void bfont_draw(uint16 *buffer, int bufwidth, int opaque, int c) { +void bfont_draw(void *buffer, int bufwidth, int opaque, int c) { bfont_draw_thin(buffer, bufwidth, opaque, c, 0); } /* Draw wide character */ -void bfont_draw_wide(uint16 *buffer, int bufwidth, int opaque, int c) { +void bfont_draw_wide(void *b, int bufwidth, int opaque, int c) { uint8 *ch = bfont_find_char_jp(c); uint16 word; int x, y; - for (y=0; y<24; ) { - /* Do the first row */ - word = (((uint16)ch[0]) << 4) | ((ch[1] >> 4) & 0x0f); - for (x=0; x<12; x++) { - if (word & (0x0800 >> x)) - *buffer = 0xffff; - else { - if (opaque) - *buffer = 0x0000; + if (!bfont_32bit) { + uint16 *buffer = (uint16 *)b; + + for (y=0; y<24; ) { + /* Do the first row */ + word = (((uint16)ch[0]) << 4) | ((ch[1] >> 4) & 0x0f); + for (x=0; x<12; x++) { + if (word & (0x0800 >> x)) + *buffer = bfont_fgcolor; + else { + if (opaque) + *buffer = bfont_bgcolor; + } + buffer++; } - buffer++; + + word = ( (((uint16)ch[1]) << 8) & 0xf00 ) | ch[2]; + for (x=0; x<12; x++) { + if (word & (0x0800 >> x)) + *buffer = bfont_fgcolor; + else { + if (opaque) + *buffer = bfont_bgcolor; + } + buffer++; + } + buffer += bufwidth - 24; + y++; + + ch += 3; } + } + else { + uint32 *buffer = (uint32 *)b; - word = ( (((uint16)ch[1]) << 8) & 0xf00 ) | ch[2]; - for (x=0; x<12; x++) { - if (word & (0x0800 >> x)) - *buffer = 0xffff; - else { - if (opaque) - *buffer = 0x0000; + for (y=0; y<24; ) { + /* Do the first row */ + word = (((uint16)ch[0]) << 4) | ((ch[1] >> 4) & 0x0f); + for (x=0; x<12; x++) { + if (word & (0x0800 >> x)) + *buffer = bfont_fgcolor; + else { + if (opaque) + *buffer = bfont_bgcolor; + } + buffer++; } - buffer++; + + word = ( (((uint16)ch[1]) << 8) & 0xf00 ) | ch[2]; + for (x=0; x<12; x++) { + if (word & (0x0800 >> x)) + *buffer = bfont_fgcolor; + else { + if (opaque) + *buffer = bfont_bgcolor; + } + buffer++; + } + buffer += bufwidth - 24; + y++; + + ch += 3; } - buffer += bufwidth - 24; - y++; - - ch += 3; } } @@ -220,8 +325,10 @@ /* Draw string of full-width (wide) and half-width (thin) characters Note that this handles the case of mixed encodings unless Japanese support is disabled (BFONT_CODE_ISO8859_1). */ -void bfont_draw_str(uint16 *buffer, int width, int opaque, char *str) { +void bfont_draw_str(void *b, int width, int opaque, char *str) { uint16 nChr, nMask, nFlag; + int adv = bfont_32bit ? 48 : 24; /* Amount to advance, in bytes */ + uint8 *buffer = (uint8 *)b; while (*str) { nFlag = 0; @@ -250,14 +357,14 @@ str++; nChr = (nChr << 8) | (*str & 0xff); bfont_draw_wide(buffer, width, opaque, nChr); - buffer += 24; + buffer += adv + adv; } else { bfont_draw_thin(buffer, width, opaque, nChr, 1); - buffer += 12; + buffer += adv; } } else { bfont_draw_thin(buffer, width, opaque, nChr, 0); - buffer += 12; + buffer += adv; } str++; } Modified: kos/kernel/arch/dreamcast/include/dc/biosfont.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/biosfont.h 2011-03-02 21:43:06 UTC (rev 704) +++ kos/kernel/arch/dreamcast/include/dc/biosfont.h 2011-03-11 22:56:59 UTC (rev 705) @@ -14,7 +14,7 @@ Japanese characters. \author Dan Potter - \author Kazuaki Matsumoto + \author Kazuaki Matsumoto */ #ifndef __DC_BIOSFONT_H @@ -25,6 +25,38 @@ #include <arch/types.h> +/** \brief Set the font foreground color. + + This function selects the foreground color to draw when a pixel is opaque in + the font. The value passed in for the color should be in whatever pixel + format that you intend to use for the image produced. + + \param c The color to use. + \return The old foreground color. +*/ +uint32 bfont_set_foreground_color(uint32 c); + +/** \brief Set the font background color. + + This function selects the background color to draw when a pixel is drawn in + the font. This color is only used for pixels not covered by the font when + you have selected to have the font be opaque. + + \param c The color to use. + \return The old background color. +*/ +uint32 bfont_set_background_color(uint32 c); + +/** \brief Set the font to draw 32-bit color. + + This function changes whether the font draws colors as 32-bit or 16-bit. The + default is to use 16-bit. + + \param on Set to 0 to use 16-bit color, 32-bit otherwise. + \return The old state (1 = 32-bit, 0 = 16-bit). +*/ +int bfont_set_32bit_mode(int on); + /* Constants for the function below */ #define BFONT_CODE_ISO8859_1 0 /**< \brief ISO-8859-1 (western) charset */ #define BFONT_CODE_EUC 1 /**< \brief EUC-JP charset */ @@ -85,40 +117,40 @@ buffer. Calling this is equivalent to calling bfont_draw_thin() with 0 for the final parameter. - \param buffer The buffer to draw to (at least 12 x 24 uint16s) + \param buffer The buffer to draw to (at least 12 x 24 pixels) \param bufwidth The width of the buffer in pixels \param opaque If non-zero, overwrite blank areas with black, otherwise do not change them from what they are \param c The character to draw */ -void bfont_draw(uint16 *buffer, int bufwidth, int opaque, int c); +void bfont_draw(void *buffer, int bufwidth, int opaque, int c); /** \brief Draw a single thin character to a buffer. This function draws a single character in the set encoding to the given buffer. This only works with ISO-8859-1 characters and half-width kana. - \param buffer The buffer to draw to (at least 12 x 24 uint16s) + \param buffer The buffer to draw to (at least 12 x 24 pixels) \param bufwidth The width of the buffer in pixels \param opaque If non-zero, overwrite blank areas with black, otherwise do not change them from what they are \param c The character to draw \param iskana Set to 1 if the character is a kana, 0 if ISO-8859-1 */ -void bfont_draw_thin(uint16 *buffer, int bufwidth, int opaque, int c, int iskana); +void bfont_draw_thin(void *buffer, int bufwidth, int opaque, int c, int iskana); /** \brief Draw a single wide character to a buffer. This function draws a single character in the set encoding to the given buffer. This only works with full-width kana and kanji. - \param buffer The buffer to draw to (at least 24 x 24 uint16s) + \param buffer The buffer to draw to (at least 24 x 24 pixels) \param bufwidth The width of the buffer in pixels \param opaque If non-zero, overwrite blank areas with black, otherwise do not change them from what they are \param c The character to draw */ -void bfont_draw_wide(uint16 *buffer, int bufwidth, int opaque, int c); +void bfont_draw_wide(void *buffer, int bufwidth, int opaque, int c); /** \brief Draw a full string to a buffer. @@ -132,7 +164,7 @@ otherwise do not change them from what they are \param str The string to draw */ -void bfont_draw_str(uint16 *buffer, int width, int opaque, char *str); +void bfont_draw_str(void *buffer, int width, int opaque, char *str); __END_DECLS This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-03-02 21:43:12
|
Revision: 704 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=704&view=rev Author: ljsebald Date: 2011-03-02 21:43:06 +0000 (Wed, 02 Mar 2011) Log Message: ----------- This aught to fix ARGB1555 support in kmgenc. Modified Paths: -------------- kos/utils/kmgenc/kmgenc.c kos/utils/kmgenc/kmgenc.h kos/utils/kmgenc/readpng.c Modified: kos/utils/kmgenc/kmgenc.c =================================================================== --- kos/utils/kmgenc/kmgenc.c 2011-02-02 08:17:42 UTC (rev 703) +++ kos/utils/kmgenc/kmgenc.c 2011-03-02 21:43:06 UTC (rev 704) @@ -90,8 +90,7 @@ out[i] = le16(PACK4444(fc.a, fc.r, fc.g, fc.b)); break; case 2: - // out[i] = le16(PACK1555(fc.a, fc.r, fc.g, fc.b)); - exit(-1); + out[i] = le16(PACK1555(fc.a, fc.r, fc.g, fc.b)); break; } } Modified: kos/utils/kmgenc/kmgenc.h =================================================================== --- kos/utils/kmgenc/kmgenc.h 2011-02-02 08:17:42 UTC (rev 703) +++ kos/utils/kmgenc/kmgenc.h 2011-03-02 21:43:06 UTC (rev 704) @@ -30,7 +30,7 @@ ( (((int)((b)*15))) << 0) ) #define PACK1555(a, r, g, b) ( \ - ( ((a) ? 0x8000 : 0x0000) | \ + ( (a) ? 0x8000 : 0x0000) | \ ( (((int)((r)*31))) << 10) | \ ( (((int)((g)*31))) << 5) | \ ( (((int)((b)*31))) << 0) ) Modified: kos/utils/kmgenc/readpng.c =================================================================== --- kos/utils/kmgenc/readpng.c 2011-02-02 08:17:42 UTC (rev 703) +++ kos/utils/kmgenc/readpng.c 2011-03-02 21:43:06 UTC (rev 704) @@ -11,6 +11,7 @@ #include <stdlib.h> #include <png.h> /* libpng header; includes zlib.h */ +#include <zlib.h> #include "readpng.h" /* typedefs, common macros, public prototypes */ static png_structp png_ptr = NULL; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <los...@us...> - 2011-02-02 08:17:49
|
Revision: 703 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=703&view=rev Author: lostgeneration Date: 2011-02-02 08:17:42 +0000 (Wed, 02 Feb 2011) Log Message: ----------- We don't actually want multiple sourcing of environ.sh to keep old values. Modified Paths: -------------- kos/doc/environ.sh.sample Modified: kos/doc/environ.sh.sample =================================================================== --- kos/doc/environ.sh.sample 2011-01-31 19:40:09 UTC (rev 702) +++ kos/doc/environ.sh.sample 2011-02-02 08:17:42 UTC (rev 703) @@ -55,6 +55,13 @@ # Manually add our second addons tree export KOS_INC_PATHS="-I${KOS_BASE}/../kos-ports/include" +# reset some options because there's no reason for them to persist across +# multiple sourcing of this +export KOS_CFLAGS="" +export KOS_CPPFLAGS="" +export KOS_LDFLAGS="" +export KOS_AFLAGS="" + # Setup some default CFLAGS for compilation. The things that will go here # are user specifyable, like optimization level and whether you want stack # traces enabled. Some platforms may have optimization restrictions, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-01-31 19:40:15
|
Revision: 702 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=702&view=rev Author: ljsebald Date: 2011-01-31 19:40:09 +0000 (Mon, 31 Jan 2011) Log Message: ----------- Add a note to the dc-chain README to not use multiple jobs with make. Modified Paths: -------------- kos/utils/dc-chain/00README Modified: kos/utils/dc-chain/00README =================================================================== --- kos/utils/dc-chain/00README 2011-01-10 05:46:04 UTC (rev 701) +++ kos/utils/dc-chain/00README 2011-01-31 19:40:09 UTC (rev 702) @@ -1,4 +1,4 @@ -dc-chain 0.1 +dc-chain 0.3 ------------ This package contains a Makefile which both simplifies building the Dreamcast @@ -22,4 +22,7 @@ Finally, run make. If anything goes wrong, check the output in logs/. Some patches are included in this package as well. As of this writing, -they patch newlib to work with KOS and gcc-3.4.6 to use POSIX threads. +they patch newlib-1.19.0 and gcc-4.5.2 to work with KOS. + +You should not attempt to spawn multiple jobs with make. Using "make -j2" or any +other number after the -j will probably break things. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-01-10 05:46:10
|
Revision: 701 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=701&view=rev Author: ljsebald Date: 2011-01-10 05:46:04 +0000 (Mon, 10 Jan 2011) Log Message: ----------- This is a little bit better version of stat(). At least this one will work for a few common use-cases of it... Modified Paths: -------------- kos/kernel/libc/newlib/newlib_stat.c Modified: kos/kernel/libc/newlib/newlib_stat.c =================================================================== --- kos/kernel/libc/newlib/newlib_stat.c 2011-01-10 04:20:29 UTC (rev 700) +++ kos/kernel/libc/newlib/newlib_stat.c 2011-01-10 05:46:04 UTC (rev 701) @@ -1,14 +1,40 @@ /* KallistiOS ##version## newlib_stat.c - Copyright (C)2004 Dan Potter + Copyright (C) 2004 Dan Potter + Copyright (C) 2011 Lawrence Sebald */ #include <unistd.h> #include <sys/stat.h> +#include <sys/reent.h> +#include <kos/fs.h> +#include <errno.h> -int _stat_r(void * reent, const char * fn, struct stat * pstat) { - pstat->st_mode = S_IFCHR; - return 0; +int _stat_r(struct _reent * reent, const char * fn, struct stat * pstat) { + file_t fp = fs_open(fn, O_RDONLY); + mode_t md = S_IFREG; + + /* If we couldn't get it as a file, try as a directory */ + if(fp == FILEHND_INVALID) { + fp = fs_open(fn, O_RDONLY | O_DIR); + md = S_IFDIR; + } + + /* If we still don't have it, then we're not going to get it. */ + if(fp == FILEHND_INVALID) { + reent->_errno = ENOENT; + return -1; + } + + /* This really doesn't convey all that much information, but it should help + with at least some uses of stat. */ + pstat->st_mode = md; + pstat->st_size = (off_t)fs_total(fp); + + /* Clean up after ourselves. */ + fs_close(fp); + + return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-01-10 04:20:35
|
Revision: 700 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=700&view=rev Author: ljsebald Date: 2011-01-10 04:20:29 +0000 (Mon, 10 Jan 2011) Log Message: ----------- Fixing up dc-chain so it builds the latest version of everything... Modified Paths: -------------- kos/utils/dc-chain/Makefile kos/utils/dc-chain/download.sh kos/utils/dc-chain/unpack.sh Modified: kos/utils/dc-chain/Makefile =================================================================== --- kos/utils/dc-chain/Makefile 2011-01-09 04:53:55 UTC (rev 699) +++ kos/utils/dc-chain/Makefile 2011-01-10 04:20:29 UTC (rev 700) @@ -3,9 +3,9 @@ # adapted from Stalin's build script version 0.3 # # Interesting parameters: -# erase=0|1 Erase build directories on the fly to save space -# thread_model=posix|single Set gcc threading model -# verbose=0|1 Display +# erase=0|1 Erase build directories on the fly to save space +# thread_model=posix|single|kos Set gcc threading model +# verbose=0|1 Display # # Interesting targets (you can 'make' any of these): # all: patch build @@ -28,14 +28,23 @@ kos_root=$(CURDIR)/../../.. # kos_base: equivalent of KOS_BASE (contains include/ and kernel/) kos_base=$(kos_root)/kos -binutils_ver=2.17 -gcc_ver=3.4.6 -newlib_ver=1.15.0 +binutils_ver=2.21 +gcc_ver=4.5.2 +newlib_ver=1.19.0 gdb_ver=6.7.1 insight_ver=6.7.1 -thread_model=posix +# With GCC 4.x versions, the patches provide a kos thread model, so you should +# use it. With 3.4.6, you probably want posix here. If you really don't want +# threading support for C++ (or Objective C/Objective C++), you can set this to +# single (why you would is beyond me, though). +thread_model=kos erase=0 -verbose=0 +verbose=1 +# Set the languages to build for pass 2 of building gcc for sh-elf. The default +# here is to build C, C++, Objective C, and Objective C++. You may want to take +# out the latter two if you're not worried about them and/or you're short on +# hard drive space. +pass2_languages=c,c++,objc,obj-c++ # Makefile variables install=$(prefix)/bin @@ -92,7 +101,7 @@ build_arm_targets=build-arm-binutils build-arm-gcc build-arm-gcc-pass1 $(build_sh4_targets): prefix = $(sh_prefix) $(build_sh4_targets): target = $(sh_target) -$(build_sh4_targets): extra_configure_args = +$(build_sh4_targets): extra_configure_args = --with-multilib-list=m4-single-only,m4-nofpu,m4 --with-endian=little --with-cpu=m4-single-only $(build_arm_targets): prefix = $(arm_prefix) $(build_arm_targets): target = $(arm_target) $(build_arm_targets): extra_configure_args = --with-arch=armv4 @@ -115,9 +124,8 @@ @echo "+++ Building $(src_dir) to $(build)..." -mkdir -p $(build) > $(log) - cd $(build); ../$(src_dir)/configure --target=$(target) --prefix=$(prefix) $(to_log) + cd $(build); ../$(src_dir)/configure --target=$(target) --prefix=$(prefix) --enable-install-libbfd $(to_log) make -C $(build) all install DESTDIR=$(DESTDIR) $(to_log) - make -C $(build)/bfd install_libbfd DESTDIR=$(DESTDIR) $(to_log) $(clean_up) $(build_gcc_pass1) $(build_gcc_pass2): build = build-gcc-$(target)-$(gcc_ver) @@ -127,8 +135,8 @@ @echo "+++ Building $(src_dir) to $(build) (pass 1)..." -mkdir -p $(build) > $(log) - cd $(build); ../$(src_dir)/configure --target=$(target) --prefix=$(prefix) --without-headers --with-newlib --enable-languages=c $(extra_configure_args) $(to_log) - make -C $(build) all-gcc install-gcc DESTDIR=$(DESTDIR) $(to_log) + cd $(build); ../$(src_dir)/configure --target=$(target) --prefix=$(prefix) --without-headers --with-newlib --enable-languages=c --disable-libssp --disable-tls $(extra_configure_args) $(to_log) + make -C $(build) all install DESTDIR=$(DESTDIR) $(to_log) $(build_newlib): build = build-newlib-$(target)-$(newlib_ver) $(build_newlib): src_dir = newlib-$(newlib_ver) @@ -137,10 +145,8 @@ @echo "+++ Building $(src_dir) to $(build)..." -mkdir -p $(build) > $(log) - cd $(build); ../$(src_dir)/configure --target=$(target) --prefix=$(prefix) $(to_log) - make -C $(build) all install CC_FOR_TARGET=$(install)/$(target)-gcc AS_FOR_TARGET=$(install)/$(target)-as \ - LD_FOR_TARGET=$(install)/$(target)-ld AR_FOR_TARGET=$(install)/$(target)-ar \ - RANLIB_FOR_TARGET=$(install)/$(target)-ranlib DESTDIR=$(DESTDIR) $(to_log) + cd $(build); ../$(src_dir)/configure --target=$(target) --prefix=$(prefix) $(extra_configure_args) $(to_log) + make -C $(build) all install DESTDIR=$(DESTDIR) $(to_log) $(clean_up) fixup-sh4-newlib: newlib_inc=$(DESTDIR)$(sh_prefix)/$(sh_target)/include @@ -164,8 +170,8 @@ @echo "+++ Building $(src_dir) to $(build) (pass 2)..." -mkdir -p $(build) > $(log) - cd $(build); ../$(src_dir)/configure --target=$(target) --prefix=$(prefix) --with-newlib \ - --enable-threads=$(thread_model) --enable-languages=c,c++ $(to_log) + cd $(build); ../$(src_dir)/configure --target=$(target) --prefix=$(prefix) --with-newlib --disable-libssp --disable-tls \ + --enable-threads=$(thread_model) --enable-languages=$(pass2_languages) $(extra_configure_args) $(to_log) make -C $(build) all install DESTDIR=$(DESTDIR) $(to_log) $(clean_up) Modified: kos/utils/dc-chain/download.sh =================================================================== --- kos/utils/dc-chain/download.sh 2011-01-09 04:53:55 UTC (rev 699) +++ kos/utils/dc-chain/download.sh 2011-01-10 04:20:29 UTC (rev 700) @@ -1,5 +1,5 @@ #!/bin/sh -wget -c ftp://ftp.gnu.org/gnu/binutils/binutils-2.17.tar.bz2 || exit 1 -wget -c ftp://ftp.gnu.org/gnu/gcc/gcc-3.4.6/gcc-3.4.6.tar.bz2 || exit 1 -wget -c ftp://sources.redhat.com/pub/newlib/newlib-1.15.0.tar.gz || exit 1 +wget -c ftp://ftp.gnu.org/gnu/binutils/binutils-2.21.tar.bz2 || exit 1 +wget -c ftp://ftp.gnu.org/gnu/gcc/gcc-4.5.2/gcc-4.5.2.tar.bz2 || exit 1 +wget -c ftp://sources.redhat.com/pub/newlib/newlib-1.19.0.tar.gz || exit 1 Modified: kos/utils/dc-chain/unpack.sh =================================================================== --- kos/utils/dc-chain/unpack.sh 2011-01-09 04:53:55 UTC (rev 699) +++ kos/utils/dc-chain/unpack.sh 2011-01-10 04:20:29 UTC (rev 700) @@ -1,7 +1,7 @@ #!/bin/sh -rm -rf binutils-2.17 gcc-3.4.6 newlib-1.15.0 +rm -rf binutils-2.21 gcc-4.5.2 newlib-1.19.0 -tar jxf binutils-2.17.tar.bz2 || exit 1 -tar jxf gcc-3.4.6.tar.bz2 || exit 1 -tar zxf newlib-1.15.0.tar.gz || exit 1 +tar jxf binutils-2.21.tar.bz2 || exit 1 +tar jxf gcc-4.5.2.tar.bz2 || exit 1 +tar zxf newlib-1.19.0.tar.gz || exit 1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2011-01-09 04:54:04
|
Revision: 699 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=699&view=rev Author: ljsebald Date: 2011-01-09 04:53:55 +0000 (Sun, 09 Jan 2011) Log Message: ----------- Adding in patches for GCC 4.5.2 and Newlib 1.19.0. These are updated for all the new stuff in the thread code. Added Paths: ----------- kos/utils/dc-chain/patches/gcc-4.5.2-kos.diff kos/utils/dc-chain/patches/newlib-1.19.0-kos.diff Added: kos/utils/dc-chain/patches/gcc-4.5.2-kos.diff =================================================================== --- kos/utils/dc-chain/patches/gcc-4.5.2-kos.diff (rev 0) +++ kos/utils/dc-chain/patches/gcc-4.5.2-kos.diff 2011-01-09 04:53:55 UTC (rev 699) @@ -0,0 +1,1955 @@ +diff -ruN gcc-4.5.2-orig/gcc/config/sh/crt1.asm gcc-4.5.2/gcc/config/sh/crt1.asm +--- gcc-4.5.2-orig/gcc/config/sh/crt1.asm 2009-04-09 11:00:19.000000000 -0400 ++++ gcc-4.5.2/gcc/config/sh/crt1.asm 2010-08-12 09:41:54.000000000 -0400 +@@ -1,1369 +1,197 @@ +-/* Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2009 +- Free Software Foundation, Inc. +- This file was pretty much copied from newlib. ++! KallistiOS ##version## ++! ++! startup.s ++! (c)2000-2001 Dan Potter ++! ++! This file must appear FIRST in your linking order, or your program won't ++! work correctly as a raw binary. ++! ++! This is very loosely based on Marcus' crt0.s/startup.s ++! ++ ++.globl start ++.globl _start ++.globl _arch_real_exit ++.globl __arch_old_sr ++.globl __arch_old_vbr ++.globl __arch_old_stack ++.globl __arch_old_fpscr + +-This file is part of GCC. +- +-GCC 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 3, or (at your option) any +-later version. +- +-GCC 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-<http://www.gnu.org/licenses/>. */ +- +- +-#ifdef MMU_SUPPORT +- /* Section used for exception/timer interrupt stack area */ +- .section .data.vbr.stack,"aw" +- .align 4 +- .global __ST_VBR +-__ST_VBR: +- .zero 1024 * 2 /* ; 2k for VBR handlers */ +-/* Label at the highest stack address where the stack grows from */ +-__timer_stack: +-#endif /* MMU_SUPPORT */ +- +- /* ;---------------------------------------- +- Normal newlib crt1.asm */ +- +-#ifdef __SH5__ +- .section .data,"aw" +- .global ___data +-___data: +- +- .section .rodata,"a" +- .global ___rodata +-___rodata: +- +-#define ICCR_BASE 0x01600000 +-#define OCCR_BASE 0x01e00000 +-#define MMUIR_BASE 0x00000000 +-#define MMUDR_BASE 0x00800000 +- +-#define PTE_ENABLED 1 +-#define PTE_DISABLED 0 +- +-#define PTE_SHARED (1 << 1) +-#define PTE_NOT_SHARED 0 +- +-#define PTE_CB_UNCACHEABLE 0 +-#define PTE_CB_DEVICE 1 +-#define PTE_CB_CACHEABLE_WB 2 +-#define PTE_CB_CACHEABLE_WT 3 +- +-#define PTE_SZ_4KB (0 << 3) +-#define PTE_SZ_64KB (1 << 3) +-#define PTE_SZ_1MB (2 << 3) +-#define PTE_SZ_512MB (3 << 3) +- +-#define PTE_PRR (1 << 6) +-#define PTE_PRX (1 << 7) +-#define PTE_PRW (1 << 8) +-#define PTE_PRU (1 << 9) +- +-#define SR_MMU_BIT 31 +-#define SR_BL_BIT 28 +- +-#define ALIGN_4KB (0xfff) +-#define ALIGN_1MB (0xfffff) +-#define ALIGN_512MB (0x1fffffff) +- +-#define DYNACON_BASE 0x0f000000 +-#define DM_CB_DLINK_BASE 0x0c000000 +-#define DM_DB_DLINK_BASE 0x0b000000 +- +-#define FEMI_AREA_0 0x00000000 +-#define FEMI_AREA_1 0x04000000 +-#define FEMI_AREA_2 0x05000000 +-#define FEMI_AREA_3 0x06000000 +-#define FEMI_AREA_4 0x07000000 +-#define FEMI_CB 0x08000000 +- +-#define EMI_BASE 0X80000000 +- +-#define DMA_BASE 0X0e000000 +- +-#define CPU_BASE 0X0d000000 +- +-#define PERIPH_BASE 0X09000000 +-#define DMAC_BASE 0x0e000000 +-#define INTC_BASE 0x0a000000 +-#define CPRC_BASE 0x0a010000 +-#define TMU_BASE 0x0a020000 +-#define SCIF_BASE 0x0a030000 +-#define RTC_BASE 0x0a040000 +- +- +- +-#define LOAD_CONST32(val, reg) \ +- movi ((val) >> 16) & 65535, reg; \ +- shori (val) & 65535, reg +- +-#define LOAD_PTEH_VAL(sym, align, bits, scratch_reg, reg) \ +- LOAD_ADDR (sym, reg); \ +- LOAD_CONST32 ((align), scratch_reg); \ +- andc reg, scratch_reg, reg; \ +- LOAD_CONST32 ((bits), scratch_reg); \ +- or reg, scratch_reg, reg +- +-#define LOAD_PTEL_VAL(sym, align, bits, scratch_reg, reg) \ +- LOAD_ADDR (sym, reg); \ +- LOAD_CONST32 ((align), scratch_reg); \ +- andc reg, scratch_reg, reg; \ +- LOAD_CONST32 ((bits), scratch_reg); \ +- or reg, scratch_reg, reg +- +-#define SET_PTE(pte_addr_reg, pteh_val_reg, ptel_val_reg) \ +- putcfg pte_addr_reg, 0, r63; \ +- putcfg pte_addr_reg, 1, ptel_val_reg; \ +- putcfg pte_addr_reg, 0, pteh_val_reg +- +-#if __SH5__ == 64 +- .section .text,"ax" +-#define LOAD_ADDR(sym, reg) \ +- movi (sym >> 48) & 65535, reg; \ +- shori (sym >> 32) & 65535, reg; \ +- shori (sym >> 16) & 65535, reg; \ +- shori sym & 65535, reg +-#else +- .mode SHmedia +- .section .text..SHmedia32,"ax" +-#define LOAD_ADDR(sym, reg) \ +- movi (sym >> 16) & 65535, reg; \ +- shori sym & 65535, reg +-#endif +- .global start ++_start: + start: +- LOAD_ADDR (_stack, r15) +- +-#ifdef MMU_SUPPORT +- ! Set up the VM using the MMU and caches +- +- ! .vm_ep is first instruction to execute +- ! after VM initialization +- pt/l .vm_ep, tr1 +- +- ! Configure instruction cache (ICCR) +- movi 3, r2 +- movi 0, r3 +- LOAD_ADDR (ICCR_BASE, r1) +- putcfg r1, 0, r2 +- putcfg r1, 1, r3 +- +- ! movi 7, r2 ! write through +- ! Configure operand cache (OCCR) +- LOAD_ADDR (OCCR_BASE, r1) +- putcfg r1, 0, r2 +- putcfg r1, 1, r3 +- +- ! Disable all PTE translations +- LOAD_ADDR (MMUIR_BASE, r1) +- LOAD_ADDR (MMUDR_BASE, r2) +- movi 64, r3 +- pt/l .disable_ptes_loop, tr0 +-.disable_ptes_loop: +- putcfg r1, 0, r63 +- putcfg r2, 0, r63 +- addi r1, 16, r1 +- addi r2, 16, r2 +- addi r3, -1, r3 +- bgt r3, r63, tr0 +- +- LOAD_ADDR (MMUIR_BASE, r1) +- +- ! FEMI instruction mappings +- ! Area 0 - 1Mb cacheable at 0x00000000 +- ! Area 1 - None +- ! Area 2 - 1Mb cacheable at 0x05000000 +- ! - 1Mb cacheable at 0x05100000 +- ! Area 3 - None +- ! Area 4 - None +- +- ! Map a 1Mb page for instructions at 0x00000000 +- LOAD_PTEH_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1Mb page for instructions at 0x05000000 +- addi r1, 16, r1 +- LOAD_PTEH_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1Mb page for instructions at 0x05100000 +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 512M page for instructions at EMI base +- addi r1, 16, r1 +- LOAD_PTEH_VAL (EMI_BASE, ALIGN_512MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (EMI_BASE, ALIGN_512MB, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRX | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 4K page for instructions at DM_DB_DLINK_BASE +- addi r1, 16, r1 +- LOAD_PTEH_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRX | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- LOAD_ADDR (MMUDR_BASE, r1) +- +- ! FEMI data mappings +- ! Area 0 - 1Mb cacheable at 0x00000000 +- ! Area 1 - 1Mb device at 0x04000000 +- ! Area 2 - 1Mb cacheable at 0x05000000 +- ! - 1Mb cacheable at 0x05100000 +- ! Area 3 - None +- ! Area 4 - None +- ! CB - 1Mb device at 0x08000000 +- +- ! Map a 1Mb page for data at 0x00000000 +- LOAD_PTEH_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1Mb page for data at 0x04000000 +- addi r1, 16, r1 +- LOAD_PTEH_VAL (FEMI_AREA_1, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (FEMI_AREA_1, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1Mb page for data at 0x05000000 +- addi r1, 16, r1 +- LOAD_PTEH_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1Mb page for data at 0x05100000 +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 4K page for registers at 0x08000000 +- addi r1, 16, r1 +- LOAD_PTEH_VAL (FEMI_CB, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (FEMI_CB, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 512M page for data at EMI +- addi r1, 16, r1 +- LOAD_PTEH_VAL (EMI_BASE, ALIGN_512MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (EMI_BASE, ALIGN_512MB, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 4K page for DYNACON at DYNACON_BASE +- addi r1, 16, r1 +- LOAD_PTEH_VAL (DYNACON_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (DYNACON_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 4K page for instructions at DM_DB_DLINK_BASE +- addi r1, 16, r1 +- LOAD_PTEH_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 4K page for data at DM_DB_DLINK_BASE+0x1000 +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((DM_DB_DLINK_BASE+0x1000), ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((DM_DB_DLINK_BASE+0x1000), ALIGN_4KB, PTE_CB_UNCACHEABLE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 4K page for stack DM_DB_DLINK_BASE+0x2000 +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((DM_DB_DLINK_BASE+0x2000), ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((DM_DB_DLINK_BASE+0x2000), ALIGN_4KB, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK +- ! 0x0c000000 - 0x0c0fffff +- addi r1, 16, r1 +- LOAD_PTEH_VAL (DM_CB_DLINK_BASE, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (DM_CB_DLINK_BASE, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK +- ! 0x0c100000 - 0x0c1fffff +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x100000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK +- ! 0x0c200000 - 0x0c2fffff +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x200000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x200000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK +- ! 0x0c400000 - 0x0c4fffff +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x400000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x400000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK +- ! 0x0c800000 - 0x0c8fffff +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x800000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x800000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map a 4K page for DMA control registers +- addi r1, 16, r1 +- LOAD_PTEH_VAL (DMA_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (DMA_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map lots of 4K pages for peripherals +- +- ! /* peripheral */ +- addi r1, 16, r1 +- LOAD_PTEH_VAL (PERIPH_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (PERIPH_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- ! /* dmac */ +- addi r1, 16, r1 +- LOAD_PTEH_VAL (DMAC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (DMAC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- ! /* intc */ +- addi r1, 16, r1 +- LOAD_PTEH_VAL (INTC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (INTC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- ! /* rtc */ +- addi r1, 16, r1 +- LOAD_PTEH_VAL (RTC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (RTC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- ! /* dmac */ +- addi r1, 16, r1 +- LOAD_PTEH_VAL (TMU_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (TMU_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- ! /* scif */ +- addi r1, 16, r1 +- LOAD_PTEH_VAL (SCIF_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (SCIF_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- ! /* cprc */ +- addi r1, 16, r1 +- LOAD_PTEH_VAL (CPRC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (CPRC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Map CPU WPC registers +- addi r1, 16, r1 +- LOAD_PTEH_VAL (CPU_BASE, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL (CPU_BASE, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- addi r1, 16, r1 +- +- LOAD_PTEH_VAL ((CPU_BASE+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((CPU_BASE+0x100000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((CPU_BASE+0x200000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((CPU_BASE+0x200000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- addi r1, 16, r1 +- LOAD_PTEH_VAL ((CPU_BASE+0x400000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) +- LOAD_PTEL_VAL ((CPU_BASE+0x400000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) +- SET_PTE (r1, r2, r3) +- +- ! Switch over to virtual addressing and enabled cache +- getcon sr, r1 +- movi 1, r2 +- shlli r2, SR_BL_BIT, r2 +- or r1, r2, r1 +- putcon r1, ssr +- getcon sr, r1 +- movi 1, r2 +- shlli r2, SR_MMU_BIT, r2 +- or r1, r2, r1 +- putcon r1, ssr +- gettr tr1, r1 +- putcon r1, spc +- synco +- rte +- +- ! VM entry point. From now on, we are in VM mode. +-.vm_ep: +- +- ! Install the trap handler, by seeding vbr with the +- ! correct value, and by assigning sr.bl = 0. +- +- LOAD_ADDR (vbr_start, r1) +- putcon r1, vbr +- movi ~(1<<28), r1 +- getcon sr, r2 +- and r1, r2, r2 +- putcon r2, sr +-#endif /* MMU_SUPPORT */ +- +- pt/l .Lzero_bss_loop, tr0 +- pt/l _init, tr5 +- pt/l ___setup_argv_and_call_main, tr6 +- pt/l _exit, tr7 +- +- ! zero out bss +- LOAD_ADDR (_edata, r0) +- LOAD_ADDR (_end, r1) +-.Lzero_bss_loop: +- stx.q r0, r63, r63 +- addi r0, 8, r0 +- bgt/l r1, r0, tr0 +- +- LOAD_ADDR (___data, r26) +- LOAD_ADDR (___rodata, r27) +- +-#ifdef __SH_FPU_ANY__ +- getcon sr, r0 +- ! enable the FP unit, by resetting SR.FD +- ! also zero out SR.FR, SR.SZ and SR.PR, as mandated by the ABI +- movi 0, r1 +- shori 0xf000, r1 +- andc r0, r1, r0 +- putcon r0, sr +-#if __SH5__ == 32 +- pt/l ___set_fpscr, tr0 +- movi 0, r4 +- blink tr0, r18 +-#endif +-#endif +- +- ! arrange for exit to call fini +- pt/l _atexit, tr1 +- LOAD_ADDR (_fini, r2) +- blink tr1, r18 +- +- ! call init +- blink tr5, r18 +- +- ! call the mainline +- blink tr6, r18 +- +- ! call exit +- blink tr7, r18 +- ! We should never return from _exit but in case we do we would enter the +- ! the following tight loop. This avoids executing any data that might follow. +-limbo: +- pt/l limbo, tr0 +- blink tr0, r63 +- +-#ifdef MMU_SUPPORT +- ! All these traps are handled in the same place. +- .balign 256 +-vbr_start: +- pt/l handler, tr0 ! tr0 trashed. +- blink tr0, r63 +- .balign 256 +-vbr_100: +- pt/l handler, tr0 ! tr0 trashed. +- blink tr0, r63 +-vbr_100_end: +- .balign 256 +-vbr_200: +- pt/l handler, tr0 ! tr0 trashed. +- blink tr0, r63 +- .balign 256 +-vbr_300: +- pt/l handler, tr0 ! tr0 trashed. +- blink tr0, r63 +- .balign 256 +-vbr_400: ! Should be at vbr+0x400 +-handler: +- /* If the trap handler is there call it */ +- LOAD_ADDR (__superh_trap_handler, r2) +- pta chandler,tr2 +- beq r2, r63, tr2 /* If zero, ie not present branch around to chandler */ +- /* Now call the trap handler with as much of the context unchanged as possible. +- Move trapping address into R18 to make it look like the trap point */ +- getcon spc, r18 +- pt/l __superh_trap_handler, tr0 +- blink tr0, r7 +-chandler: +- getcon spc, r62 +- getcon expevt, r2 +- pt/l _exit, tr0 +- blink tr0, r63 +- +- /* Simulated trap handler */ +- .section .text..SHmedia32,"ax" +-gcc2_compiled.: +- .section .debug_abbrev +-.Ldebug_abbrev0: +- .section .text..SHmedia32 +-.Ltext0: +- .section .debug_info +-.Ldebug_info0: +- .section .debug_line +-.Ldebug_line0: +- .section .text..SHmedia32,"ax" +- .align 5 +- .global __superh_trap_handler +- .type __superh_trap_handler,@function +-__superh_trap_handler: +-.LFB1: +- ptabs r18, tr0 +- addi.l r15, -8, r15 +- st.l r15, 4, r14 +- addi.l r15, -8, r15 +- add.l r15, r63, r14 +- st.l r14, 0, r2 +- ptabs r7, tr0 +- addi.l r14, 8, r14 +- add.l r14, r63, r15 +- ld.l r15, 4, r14 +- addi.l r15, 8, r15 +- blink tr0, r63 +-.LFE1: +-.Lfe1: +- .size __superh_trap_handler,.Lfe1-__superh_trap_handler +- +- .section .text..SHmedia32 +-.Letext0: +- +- .section .debug_info +- .ualong 0xa7 +- .uaword 0x2 +- .ualong .Ldebug_abbrev0 +- .byte 0x4 +- .byte 0x1 +- .ualong .Ldebug_line0 +- .ualong .Letext0 +- .ualong .Ltext0 +- .string "trap_handler.c" +- +- .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxx" +- +- .string "GNU C 2.97-sh5-010522" +- +- .byte 0x1 +- .byte 0x2 +- .ualong 0x9a +- .byte 0x1 +- .string "_superh_trap_handler" +- +- .byte 0x1 +- .byte 0x2 +- .byte 0x1 +- .ualong .LFB1 +- .ualong .LFE1 +- .byte 0x1 +- .byte 0x5e +- .byte 0x3 +- .string "trap_reason" +- +- .byte 0x1 +- .byte 0x1 +- .ualong 0x9a +- .byte 0x2 +- .byte 0x91 +- .byte 0x0 +- .byte 0x0 +- .byte 0x4 +- .string "unsigned int" +- +- .byte 0x4 +- .byte 0x7 +- .byte 0x0 +- +- .section .debug_abbrev +- .byte 0x1 +- .byte 0x11 +- .byte 0x1 +- .byte 0x10 +- .byte 0x6 +- .byte 0x12 +- .byte 0x1 +- .byte 0x11 +- .byte 0x1 +- .byte 0x3 +- .byte 0x8 +- .byte 0x1b +- .byte 0x8 +- .byte 0x25 +- .byte 0x8 +- .byte 0x13 +- .byte 0xb +- .byte 0,0 +- .byte 0x2 +- .byte 0x2e +- .byte 0x1 +- .byte 0x1 +- .byte 0x13 +- .byte 0x3f +- .byte 0xc +- .byte 0x3 +- .byte 0x8 +- .byte 0x3a +- .byte 0xb +- .byte 0x3b +- .byte 0xb +- .byte 0x27 +- .byte 0xc +- .byte 0x11 +- .byte 0x1 +- .byte 0x12 +- .byte 0x1 +- .byte 0x40 +- .byte 0xa +- .byte 0,0 +- .byte 0x3 +- .byte 0x5 +- .byte 0x0 +- .byte 0x3 +- .byte 0x8 +- .byte 0x3a +- .byte 0xb +- .byte 0x3b +- .byte 0xb +- .byte 0x49 +- .byte 0x13 +- .byte 0x2 +- .byte 0xa +- .byte 0,0 +- .byte 0x4 +- .byte 0x24 +- .byte 0x0 +- .byte 0x3 +- .byte 0x8 +- .byte 0xb +- .byte 0xb +- .byte 0x3e +- .byte 0xb +- .byte 0,0 +- .byte 0 +- +- .section .debug_pubnames +- .ualong 0x27 +- .uaword 0x2 +- .ualong .Ldebug_info0 +- .ualong 0xab +- .ualong 0x5b +- .string "_superh_trap_handler" +- +- .ualong 0x0 +- +- .section .debug_aranges +- .ualong 0x1c +- .uaword 0x2 +- .ualong .Ldebug_info0 +- .byte 0x4 +- .byte 0x0 +- .uaword 0x0,0 +- .ualong .Ltext0 +- .ualong .Letext0-.Ltext0 +- .ualong 0x0 +- .ualong 0x0 +- .ident "GCC: (GNU) 2.97-sh5-010522" +-#endif /* MMU_SUPPORT */ +-#else /* ! __SH5__ */ +- +- ! make a place to keep any previous value of the vbr register +- ! this will only have a value if it has been set by redboot (for example) +- .section .bss +-old_vbr: +- .long 0 +-#ifdef PROFILE +-profiling_enabled: +- .long 0 +-#endif +- +- +- .section .text +- .global start +- .import ___rtos_profiler_start_timer +- .weak ___rtos_profiler_start_timer +-start: +- mov.l stack_k,r15 +- +-#if defined (__SH3__) || (defined (__SH_FPU_ANY__) && ! defined (__SH2A__)) || defined (__SH4_NOFPU__) +-#define VBR_SETUP +- ! before zeroing the bss ... +- ! if the vbr is already set to vbr_start then the program has been restarted +- ! (i.e. it is not the first time the program has been run since reset) +- ! reset the vbr to its old value before old_vbr (in bss) is wiped +- ! this ensures that the later code does not create a circular vbr chain +- stc vbr, r1 +- mov.l vbr_start_k, r2 +- cmp/eq r1, r2 +- bf 0f +- ! reset the old vbr value +- mov.l old_vbr_k, r1 +- mov.l @r1, r2 +- ldc r2, vbr +-0: +-#endif /* VBR_SETUP */ +- +- ! zero out bss +- mov.l edata_k,r0 +- mov.l end_k,r1 +- mov #0,r2 +-start_l: +- mov.l r2,@r0 +- add #4,r0 +- cmp/ge r0,r1 +- bt start_l +- +-#if defined (__SH_FPU_ANY__) +- mov.l set_fpscr_k, r1 +- mov #4,r4 +- jsr @r1 +- shll16 r4 ! Set DN bit (flush denormal inputs to zero) +- lds r3,fpscr ! Switch to default precision +-#endif /* defined (__SH_FPU_ANY__) */ +- +-#ifdef VBR_SETUP +- ! save the existing contents of the vbr +- ! there will only be a prior value when using something like redboot +- ! otherwise it will be zero +- stc vbr, r1 +- mov.l old_vbr_k, r2 +- mov.l r1, @r2 +- ! setup vbr +- mov.l vbr_start_k, r1 +- ldc r1,vbr +-#endif /* VBR_SETUP */ +- +- ! if an rtos is exporting a timer start fn, +- ! then pick up an SR which does not enable ints +- ! (the rtos will take care of this) +- mov.l rtos_start_fn, r0 +- mov.l sr_initial_bare, r1 +- tst r0, r0 +- bt set_sr +- +- mov.l sr_initial_rtos, r1 +- +-set_sr: +- ! Set status register (sr) +- ldc r1, sr +- +- ! arrange for exit to call fini +- mov.l atexit_k,r0 +- mov.l fini_k,r4 +- jsr @r0 ++ ! Disable interrupts (if they're enabled) ++ mov.l old_sr_addr,r0 ++ stc sr,r1 ++ mov.l r1,@r0 ++ mov.l init_sr,r0 ++ ldc r0,sr ++ ++ ! Run in the P2 area ++ mov.l setup_cache_addr,r0 ++ mov.l p2_mask,r1 ++ or r1,r0 ++ jmp @r0 + nop + +-#ifdef PROFILE +- ! arrange for exit to call _mcleanup (via stop_profiling) +- mova stop_profiling,r0 +- mov.l atexit_k,r1 +- jsr @r1 +- mov r0, r4 +- +- ! Call profiler startup code +- mov.l monstartup_k, r0 +- mov.l start_k, r4 +- mov.l etext_k, r5 +- jsr @r0 ++setup_cache: ++ ! Now that we are in P2, it's safe to enable the cache ++ ! Check to see if we should enable OCRAM. ++ mov.l kos_init_flags_addr, r0 ++ add #2, r0 ++ mov.w @r0, r0 ++ tst #1, r0 ++ bf .L_setup_cache_L0 ++ mov.w ccr_data,r1 ++ bra .L_setup_cache_L1 ++ nop ++.L_setup_cache_L0: ++ mov.w ccr_data_ocram,r1 ++.L_setup_cache_L1: ++ mov.l ccr_addr,r0 ++ mov.l r1,@r0 ++ ++ ! After changing CCR, eight instructions must be executed before ++ ! it's safe to enter a cached area such as P1 ++ nop ! 1 ++ nop ! 2 ++ nop ! 3 ++ nop ! 4 ++ nop ! 5 (d-cache now safe) ++ nop ! 6 ++ mov.l init_addr,r0 ! 7 ++ mov #0,r1 ! 8 ++ jmp @r0 ! go ++ mov r1,r0 + nop + +- ! enable profiling trap +- ! until now any trap 33s will have been ignored +- ! This means that all library functions called before this point +- ! (directly or indirectly) may have the profiling trap at the start. +- ! Therefore, only mcount itself may not have the extra header. +- mov.l profiling_enabled_k2, r0 +- mov #1, r1 +- mov.l r1, @r0 +-#endif /* PROFILE */ ++init: ++ ! Save old PR on old stack so we can get to it later ++ sts.l pr,@-r15 + +- ! call init +- mov.l init_k,r0 ++ ! Save the current stack, and set a new stack (higher up in RAM) ++ mov.l old_stack_addr,r0 ++ mov.l r15,@r0 ++ mov.l new_stack,r15 ++ ++ ! Save VBR ++ mov.l old_vbr_addr,r0 ++ stc vbr,r1 ++ mov.l r1,@r0 ++ ++ ! Save FPSCR ++ mov.l old_fpscr_addr,r0 ++ sts fpscr,r1 ++ mov.l r1,@r0 ++ ++ ! Reset FPSCR ++ mov #4,r4 ! Use 00040000 (DN=1) ++ mov.l fpscr_addr,r0 + jsr @r0 +- nop ++ shll16 r4 + +- ! call the mainline +- mov.l main_k,r0 +- jsr @r0 +- nop ++ ! Setup a sentinel value for frame pointer in case we're using ++ ! FRAME_POINTERS for stack tracing. ++ mov #-1,r14 + +- ! call exit +- mov r0,r4 +- mov.l exit_k,r0 ++ ! Jump to the kernel main ++ mov.l main_addr,r0 + jsr @r0 + nop +- +- .balign 4 +-#ifdef PROFILE +-stop_profiling: +- # stop mcount counting +- mov.l profiling_enabled_k2, r0 +- mov #0, r1 +- mov.l r1, @r0 +- +- # call mcleanup +- mov.l mcleanup_k, r0 +- jmp @r0 +- nop +- +- .balign 4 +-mcleanup_k: +- .long __mcleanup +-monstartup_k: +- .long ___monstartup +-profiling_enabled_k2: +- .long profiling_enabled +-start_k: +- .long _start +-etext_k: +- .long __etext +-#endif /* PROFILE */ + +- .align 2 +-#if defined (__SH_FPU_ANY__) +-set_fpscr_k: +- .long ___set_fpscr +-#endif /* defined (__SH_FPU_ANY__) */ ++ ! Program can return here (not likely) or jump here directly ++ ! from anywhere in it to go straight back to the monitor ++_arch_real_exit: ++ ! Reset SR ++ mov.l old_sr,r0 ++ ldc r0,sr ++ ++ ! Disable MMU, invalidate TLB ++ mov #4,r0 ++ mov.l mmu_addr,r1 ++ mov.l r0,@r1 ++ ++ ! Wait (just in case) ++ nop ! 1 ++ nop ! 2 ++ nop ! 3 ++ nop ! 4 ++ nop ! 5 ++ nop ! 6 ++ nop ! 7 ++ nop ! 8 ++ ++ ! Restore VBR ++ mov.l old_vbr,r0 ++ ldc r0,vbr + +-stack_k: +- .long _stack +-edata_k: +- .long _edata +-end_k: +- .long _end +-main_k: +- .long ___setup_argv_and_call_main +-exit_k: +- .long _exit +-atexit_k: +- .long _atexit +-init_k: +- .long _init +-fini_k: +- .long _fini +-#ifdef VBR_SETUP +-old_vbr_k: +- .long old_vbr +-vbr_start_k: +- .long vbr_start +-#endif /* VBR_SETUP */ +- +-sr_initial_rtos: +- ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work. +- ! Whether profiling or not, keep interrupts masked, +- ! the RTOS will enable these if required. +- .long 0x600000f1 +- +-rtos_start_fn: +- .long ___rtos_profiler_start_timer +- +-#ifdef PROFILE +-sr_initial_bare: +- ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work. +- ! For bare machine, we need to enable interrupts to get profiling working +- .long 0x60000001 +-#else ++ ! If we're working under dcload, call its EXIT syscall ++ mov.l dcload_magic_addr,r0 ++ mov.l @r0,r0 ++ mov.l dcload_magic_value,r1 ++ cmp/eq r0,r1 ++ bf normal_exit + +-sr_initial_bare: +- ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work. +- ! Keep interrupts disabled - the application will enable as required. +- .long 0x600000f1 +-#endif ++ mov.l dcload_syscall,r0 ++ mov.l @r0,r0 ++ jsr @r0 ++ mov #15,r4 + +- ! supplied for backward compatibility only, in case of linking +- ! code whose main() was compiled with an older version of GCC. +- .global ___main +-___main: ++ ! Set back the stack and return (presumably to a serial debug) ++normal_exit: ++ mov.l old_stack,r15 ++ lds.l @r15+,pr + rts + nop +-#ifdef VBR_SETUP +-! Exception handlers +- .section .text.vbr, "ax" +-vbr_start: +- +- .org 0x100 +-vbr_100: +-#ifdef PROFILE +- ! Note on register usage. +- ! we use r0..r3 as scratch in this code. If we are here due to a trapa for profiling +- ! then this is OK as we are just before executing any function code. +- ! The other r4..r7 we save explicityl on the stack +- ! Remaining registers are saved by normal ABI conventions and we assert we do not +- ! use floating point registers. +- mov.l expevt_k1, r1 +- mov.l @r1, r1 +- mov.l event_mask, r0 +- and r0,r1 +- mov.l trapcode_k, r2 +- cmp/eq r1,r2 +- bt 1f +- bra handler_100 ! if not a trapa, go to default handler +- nop +-1: +- mov.l trapa_k, r0 +- mov.l @r0, r0 +- shlr2 r0 ! trapa code is shifted by 2. +- cmp/eq #33, r0 +- bt 2f +- bra handler_100 +- nop +-2: +- +- ! If here then it looks like we have trap #33 +- ! Now we need to call mcount with the following convention +- ! Save and restore r4..r7 +- mov.l r4,@-r15 +- mov.l r5,@-r15 +- mov.l r6,@-r15 +- mov.l r7,@-r15 +- sts.l pr,@-r15 +- +- ! r4 is frompc. +- ! r5 is selfpc +- ! r0 is the branch back address. +- ! The code sequence emitted by gcc for the profiling trap is +- ! .align 2 +- ! trapa #33 +- ! .align 2 +- ! .long lab Where lab is planted by the compiler. This is the address +- ! of a datum that needs to be incremented. +- sts pr, r4 ! frompc +- stc spc, r5 ! selfpc +- mov #2, r2 +- not r2, r2 ! pattern to align to 4 +- and r2, r5 ! r5 now has aligned address +-! add #4, r5 ! r5 now has address of address +- mov r5, r2 ! Remember it. +-! mov.l @r5, r5 ! r5 has value of lable (lab in above example) +- add #8, r2 +- ldc r2, spc ! our return address avoiding address word +- +- ! only call mcount if profiling is enabled +- mov.l profiling_enabled_k, r0 +- mov.l @r0, r0 +- cmp/eq #0, r0 +- bt 3f +- ! call mcount +- mov.l mcount_k, r2 +- jsr @r2 +- nop +-3: +- lds.l @r15+,pr +- mov.l @r15+,r7 +- mov.l @r15+,r6 +- mov.l @r15+,r5 +- mov.l @r15+,r4 +- rte +- nop +- .balign 4 +-event_mask: +- .long 0xfff +-trapcode_k: +- .long 0x160 +-expevt_k1: +- .long 0xff000024 ! Address of expevt +-trapa_k: +- .long 0xff000020 +-mcount_k: +- .long __call_mcount +-profiling_enabled_k: +- .long profiling_enabled +-#endif +- ! Non profiling case. +-handler_100: +- mov.l 2f, r0 ! load the old vbr setting (if any) +- mov.l @r0, r0 +- cmp/eq #0, r0 +- bf 1f +- ! no previous vbr - jump to own generic handler +- bra handler +- nop +-1: ! there was a previous handler - chain them +- add #0x7f, r0 ! 0x7f +- add #0x7f, r0 ! 0xfe +- add #0x2, r0 ! add 0x100 without corrupting another register +- jmp @r0 +- nop +- .balign 4 +-2: +- .long old_vbr + +- .org 0x400 +-vbr_400: ! Should be at vbr+0x400 +- mov.l 2f, r0 ! load the old vbr setting (if any) +- mov.l @r0, r0 +- cmp/eq #0, r0 +- ! no previous vbr - jump to own generic handler +- bt handler +- ! there was a previous handler - chain them +- rotcr r0 +- rotcr r0 +- add #0x7f, r0 ! 0x1fc +- add #0x7f, r0 ! 0x3f8 +- add #0x02, r0 ! 0x400 +- rotcl r0 +- rotcl r0 ! Add 0x400 without corrupting another register +- jmp @r0 +- nop +- .balign 4 +-2: +- .long old_vbr +-handler: +- /* If the trap handler is there call it */ +- mov.l superh_trap_handler_k, r0 +- cmp/eq #0, r0 ! True if zero. +- bf 3f +- bra chandler +- nop +-3: +- ! Here handler available, call it. +- /* Now call the trap handler with as much of the context unchanged as possible. +- Move trapping address into PR to make it look like the trap point */ +- stc spc, r1 +- lds r1, pr +- mov.l expevt_k, r4 +- mov.l @r4, r4 ! r4 is value of expevt, first parameter. +- mov r1, r5 ! Remember trapping pc. +- mov r1, r6 ! Remember trapping pc. +- mov.l chandler_k, r1 +- mov.l superh_trap_handler_k, r2 +- ! jmp to trap handler to avoid disturbing pr. +- jmp @r2 +- nop +- +- .org 0x600 +-vbr_600: +-#ifdef PROFILE +- ! Should be at vbr+0x600 +- ! Now we are in the land of interrupts so need to save more state. +- ! Save register state +- mov.l interrupt_stack_k, r15 ! r15 has been saved to sgr. +- mov.l r0,@-r15 +- mov.l r1,@-r15 +- mov.l r2,@-r15 +- mov.l r3,@-r15 +- mov.l r4,@-r15 +- mov.l r5,@-r15 +- mov.l r6,@-r15 +- mov.l r7,@-r15 +- sts.l pr,@-r15 +- sts.l mach,@-r15 +- sts.l macl,@-r15 +-#if defined(__SH_FPU_ANY__) +- ! Save fpul and fpscr, save fr0-fr7 in 64 bit mode +- ! and set the pervading precision for the timer_handler +- mov #0,r0 +- sts.l fpul,@-r15 +- sts.l fpscr,@-r15 +- lds r0,fpscr ! Clear fpscr +- fmov fr0,@-r15 +- fmov fr1,@-r15 +- fmov fr2,@-r15 +- fmov fr3,@-r15 +- mov.l pervading_precision_k,r0 +- fmov fr4,@-r15 +- fmov fr5,@-r15 +- mov.l @r0,r0 +- fmov fr6,@-r15 +- fmov fr7,@-r15 +- lds r0,fpscr +-#endif /* __SH_FPU_ANY__ */ +- ! Pass interrupted pc to timer_handler as first parameter (r4). +- stc spc, r4 +- mov.l timer_handler_k, r0 +- jsr @r0 +- nop +-#if defined(__SH_FPU_ANY__) +- mov #0,r0 +- lds r0,fpscr ! Clear the fpscr +- fmov @r15+,fr7 +- fmov @r15+,fr6 +- fmov @r15+,fr5 +- fmov @r15+,fr4 +- fmov @r15+,fr3 +- fmov @r15+,fr2 +- fmov @r15+,fr1 +- fmov @r15+,fr0 +- lds.l @r15+,fpscr +- lds.l @r15+,fpul +-#endif /* __SH_FPU_ANY__ */ +- lds.l @r15+,macl +- lds.l @r15+,mach +- lds.l @r15+,pr +- mov.l @r15+,r7 +- mov.l @r15+,r6 +- mov.l @r15+,r5 +- mov.l @r15+,r4 +- mov.l @r15+,r3 +- mov.l @r15+,r2 +- mov.l @r15+,r1 +- mov.l @r15+,r0 +- stc sgr, r15 ! Restore r15, destroyed by this sequence. +- rte +- nop +-#if defined(__SH_FPU_ANY__) +- .balign 4 +-pervading_precision_k: +-#define CONCAT1(A,B) A##B +-#define CONCAT(A,B) CONCAT1(A,B) +- .long CONCAT(__USER_LABEL_PREFIX__,__fpscr_values)+4 +-#endif +-#else +- mov.l 2f, r0 ! Load the old vbr setting (if any). +- mov.l @r0, r0 +- cmp/eq #0, r0 +- ! no previous vbr - jump to own handler +- bt chandler +- ! there was a previous handler - chain them +- rotcr r0 +- rotcr r0 +- add #0x7f, r0 ! 0x1fc +- add #0x7f, r0 ! 0x3f8 +- add #0x7f, r0 ! 0x5f4 +- add #0x03, r0 ! 0x600 +- rotcl r0 +- rotcl r0 ! Add 0x600 without corrupting another register +- jmp @r0 +- nop +- .balign 4 +-2: +- .long old_vbr +-#endif /* PROFILE code */ +-chandler: +- mov.l expevt_k, r4 +- mov.l @r4, r4 ! r4 is value of expevt hence making this the return code +- mov.l handler_exit_k,r0 +- jsr @r0 +- nop +- ! We should never return from _exit but in case we do we would enter the +- ! the following tight loop +-limbo: +- bra limbo +- nop +- .balign 4 +-#ifdef PROFILE +-interrupt_stack_k: +- .long __timer_stack ! The high end of the stack +-timer_handler_k: +- .long __profil_counter +-#endif +-expevt_k: +- .long 0xff000024 ! Address of expevt +-chandler_k: +- .long chandler +-superh_trap_handler_k: +- .long __superh_trap_handler +-handler_exit_k: +- .long _exit +- .align 2 +-! Simulated compile of trap handler. +- .section .debug_abbrev,"",@progbits +-.Ldebug_abbrev0: +- .section .debug_info,"",@progbits +-.Ldebug_info0: +- .section .debug_line,"",@progbits +-.Ldebug_line0: +- .text +-.Ltext0: +- .align 5 +- .type __superh_trap_handler,@function +-__superh_trap_handler: +-.LFB1: +- mov.l r14,@-r15 +-.LCFI0: +- add #-4,r15 +-.LCFI1: +- mov r15,r14 +-.LCFI2: +- mov.l r4,@r14 +- lds r1, pr +- add #4,r14 +- mov r14,r15 +- mov.l @r15+,r14 +- rts +- nop +-.LFE1: +-.Lfe1: +- .size __superh_trap_handler,.Lfe1-__superh_trap_handler +- .section .debug_frame,"",@progbits +-.Lframe0: +- .ualong .LECIE0-.LSCIE0 +-.LSCIE0: +- .ualong 0xffffffff +- .byte 0x1 +- .string "" +- .uleb128 0x1 +- .sleb128 -4 +- .byte 0x11 +- .byte 0xc +- .uleb128 0xf +- .uleb128 0x0 +- .align 2 +-.LECIE0: +-.LSFDE0: +- .ualong .LEFDE0-.LASFDE0 +-.LASFDE0: +- .ualong .Lframe0 +- .ualong .LFB1 +- .ualong .LFE1-.LFB1 +- .byte 0x4 +- .ualong .LCFI0-.LFB1 +- .byte 0xe +- .uleb128 0x4 +- .byte 0x4 +- .ualong .LCFI1-.LCFI0 +- .byte 0xe +- .uleb128 0x8 +- .byte 0x8e +- .uleb128 0x1 +- .byte 0x4 +- .ualong .LCFI2-.LCFI1 +- .byte 0xd +- .uleb128 0xe +- .align 2 +-.LEFDE0: +- .text +-.Letext0: +- .section .debug_info +- .ualong 0xb3 +- .uaword 0x2 +- .ualong .Ldebug_abbrev0 +- .byte 0x4 +- .uleb128 0x1 +- .ualong .Ldebug_line0 +- .ualong .Letext0 +- .ualong .Ltext0 +- .string "trap_handler.c" +- .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxx" +- .string "GNU C 3.2 20020529 (experimental)" +- .byte 0x1 +- .uleb128 0x2 +- .ualong 0xa6 +- .byte 0x1 +- .string "_superh_trap_handler" +- .byte 0x1 +- .byte 0x2 +- .byte 0x1 +- .ualong .LFB1 +- .ualong .LFE1 +- .byte 0x1 +- .byte 0x5e +- .uleb128 0x3 +- .string "trap_reason" +- .byte 0x1 +- .byte 0x1 +- .ualong 0xa6 +- .byte 0x2 +- .byte 0x91 +- .sleb128 0 +- .byte 0x0 +- .uleb128 0x4 +- .string "unsigned int" +- .byte 0x4 +- .byte 0x7 +- .byte 0x0 +- .section .debug_abbrev +- .uleb128 0x1 +- .uleb128 0x11 +- .byte 0x1 +- .uleb128 0x10 +- .uleb128 0x6 +- .uleb128 0x12 +- .uleb128 0x1 +- .uleb128 0x11 +- .uleb128 0x1 +- .uleb128 0x3 +- .uleb128 0x8 +- .uleb128 0x1b +- .uleb128 0x8 +- .uleb128 0x25 +- .uleb128 0x8 +- .uleb128 0x13 +- .uleb128 0xb +- .byte 0x0 +- .byte 0x0 +- .uleb128 0x2 +- .uleb128 0x2e +- .byte 0x1 +- .uleb128 0x1 +- .uleb128 0x13 +- .uleb128 0x3f +- .uleb128 0xc +- .uleb128 0x3 +- .uleb128 0x8 +- .uleb128 0x3a +- .uleb128 0xb +- .uleb128 0x3b +- .uleb128 0xb +- .uleb128 0x27 +- .uleb128 0xc +- .uleb128 0x11 +- .uleb128 0x1 +- .uleb128 0x12 +- .uleb128 0x1 +- .uleb128 0x40 +- .uleb128 0xa +- .byte 0x0 +- .byte 0x0 +- .uleb128 0x3 +- .uleb128 0x5 +- .byte 0x0 +- .uleb128 0x3 +- .uleb128 0x8 +- .uleb128 0x3a +- .uleb128 0xb +- .uleb128 0x3b +- .uleb128 0xb +- .uleb128 0x49 +- .uleb128 0x13 +- .uleb128 0x2 +- .uleb128 0xa +- .byte 0x0 +- .byte 0x0 +- .uleb128 0x4 +- .uleb128 0x24 +- .byte 0x0 +- .uleb128 0x3 +- .uleb128 0x8 +- .uleb128 0xb +- .uleb128 0xb +- .uleb128 0x3e +- .uleb128 0xb +- .byte 0x0 +- .byte 0x0 +- .byte 0x0 +- .section .debug_pubnames,"",@progbits +- .ualong 0x27 +- .uaword 0x2 +- .ualong .Ldebug_info0 +- .ualong 0xb7 +- .ualong 0x67 +- .string "_superh_trap_handler" +- .ualong 0x0 +- .section .debug_aranges,"",@progbits +- .ualong 0x1c +- .uaword 0x2 +- .ualong .Ldebug_info0 +- .byte 0x4 +- .byte 0x0 +- .uaword 0x0 +- .uaword 0x0 +- .ualong .Ltext0 +- .ualong .Letext0-.Ltext0 +- .ualong 0x0 +- .ualong 0x0 +-#endif /* VBR_SETUP */ +-#endif /* ! __SH5__ */ ++! Misc variables ++ .align 2 ++dcload_magic_addr: ++ .long 0x8c004004 ++dcload_magic_value: ++ .long 0xdeadbeef ++dcload_syscall: ++ .long 0x8c004008 ++__arch_old_sr: ++old_sr: ++ .long 0 ++__arch_old_vbr: ++old_vbr: ++ .long 0 ++__arch_old_fpscr: ++old_fpscr: ++ .long 0 ++init_sr: ++ .long 0x500000f0 ++old_sr_addr: ++ .long old_sr ++old_vbr_addr: ++ .long old_vbr ++old_fpscr_addr: ++ .long old_fpscr ++old_stack_addr: ++ .long old_stack ++__arch_old_stack: ++old_stack: ++ .long 0 ++new_stack: ++ .long 0x8d000000 ++p2_mask: ++ .long 0xa0000000 ++setup_cache_addr: ++ .long setup_cache ++init_addr: ++ .long init ++main_addr: ++ .long _arch_main ++mmu_addr: ++ .long 0xff000010 ++fpscr_addr: ++ .long ___set_fpscr ! in libgcc ++kos_init_flags_addr: ++ .long ___kos_init_flags ++ccr_addr: ++ .long 0xff00001c ++ccr_data: ++ .word 0x090d ++ccr_data_ocram: ++ .word 0x092d +diff -ruN gcc-4.5.2-orig/gcc/configure gcc-4.5.2/gcc/configure +--- gcc-4.5.2-orig/gcc/configure 2010-12-03 07:35:37.000000000 -0500 ++++ gcc-4.5.2/gcc/configure 2011-01-07 23:18:44.000000000 -0500 +@@ -10421,7 +10421,7 @@ + target_thread_file='single' + ;; + aix | dce | gnat | irix | posix | posix95 | rtems | \ +- single | solaris | vxworks | win32 | mipssde) ++ single | solaris | vxworks | win32 | mipssde | kos) + target_thread_file=${enable_threads} + ;; + *) +diff -ruN gcc-4.5.2-orig/gcc/gthr-kos.h gcc-4.5.2/gcc/gthr-kos.h +--- gcc-4.5.2-orig/gcc/gthr-kos.h 1969-12-31 19:00:00.000000000 -0500 ++++ gcc-4.5.2/gcc/gthr-kos.h 2011-01-08 23:30:52.000000000 -0500 +@@ -0,0 +1,388 @@ ++/* Copyright (C) 2009, 2010, 2011 Lawrence Sebald */ ++ ++/* Threads compatibility routines for libgcc2 and libobjc. */ ++/* Compile this one with gcc. */ ++/* Copyright (C) 1997, 1999, 2000, 2004, 2008, 2009 ++ Free Software Foundation, Inc. ++ ++This file is part of GCC. ++ ++GCC 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 3, or (at your option) any later ++version. ++ ++GCC 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. ++ ++Under Section 7 of GPL version 3, you are granted additional ++permissions described in the GCC Runtime Library Exception, version ++3.1, as published by the Free Software Foundation. ++ ++You should have received a copy of the GNU General Public License and ++a copy of the GCC Runtime Library Exception along with this program; ++see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++<http://www.gnu.org/licenses/>. */ ++ ++#ifndef GCC_GTHR_KOS_H ++#define GCC_GTHR_KOS_H ++ ++/* KallistiOS threads specific definitions. */ ++ ++#define __GTHREADS 1 ++#define __GTHREADS_CXX0X 1 ++#define __GTHREAD_HAS_COND 1 ++ ++#include <assert.h> ++#include <kos/thread.h> ++#include <kos/tls.h> ++#include <kos/mutex.h> ++#include <kos/recursive_lock.h> ++#include <kos/once.h> ++#include <kos/cond.h> ++#include <time.h> ++ ++/* These should work just fine. */ ++typedef kthread_key_t __gthread_key_t; ++typedef kthread_once_t __gthread_once_t; ++typedef mutex_t * __gthread_mutex_t; ++typedef recursive_lock_t * __gthread_recursive_mutex_t; ++typedef condvar_t * __gthread_cond_t; ++typedef kthread_t * __gthread_t; ++typedef struct timespec __gthread_time_t; ++ ++static void __gthr_mutex_init(__gthread_mutex_t *__mutex) { ++ assert(__mutex); ++ *__mutex = mutex_create(); ++} ++ ++static void __gthr_recursive_mutex_init(__gthread_recursive_mutex_t *__mutex) { ++ assert(__mutex); ++ *__mutex = rlock_create(); ++} ++ ++static void __gthr_cond_init(__gthread_cond_t *__cond) { ++ assert(__cond); ++ *__cond = cond_create(); ++} ++ ++#define __GTHREAD_ONCE_INIT KTHREAD_ONCE_INIT ++#define __GTHREAD_MUTEX_INIT_FUNCTION __gthr_mutex_init ++#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthr_recursive_mutex_init ++#define __GTHREAD_COND_INIT_FUNCTION __gthr_cond_init ++ ++static inline int __gthread_active_p(void) { ++ return 1; ++} ++ ++#ifdef _LIBOBJC ++ ++/* This stuff only applies to Objective C. */ ++ ++/* The config.h file in libobjc/ */ ++#include <config.h> ++ ++/* Key structure for maintaining thread specific storage */ ++static kthread_key_t _objc_thread_storage; ++ ++/* Backend initialization funcitons */ ++ ++/* Initialize the threads subsystem. */ ++static inline int __gthread_objc_init_thread_system(void) { ++ /* The only thing we have to do is to initialize the storage key. */ ++ return kthread_key_create(&_objc_thread_storage, NULL); ++} ++ ++/* Close the threads subsystem. */ ++static inline int __gthread_objc_close_thread_system(void) { ++ return kthread_key_delete(_objc_thread_storage); ++} ++ ++/* Backend thread functions */ ++ ++/* Create a new thread of execution. */ ++static inline objc_thread_t __gthread_objc_thread_detach(void (*func)(void *), ++ void *arg) { ++ kthread_t *thd_hnd; ++ ++ thd_hnd = thd_create(1, (void *)(void *)func, arg); ++ return (objc_thread_t)thd_hnd; ++} ++ ++/* Set the current thread's priority. */ ++static inline int __gthread_objc_thread_set_priority(int priority __attribute__((unused))) { ++ /* XXXX */ ++ return -1; ++} ++ ++/* Return the current thread's priority. */ ++static inline int __gthread_objc_thread_get_priority(void) { ++ /* XXXX */ ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++} ++ ++/* Yield our process time to another thread. */ ++static inline void __gthread_objc_thread_yield(void) { ++ thd_pass(); ++} ++ ++/* Terminate the current thread. */ ++static inline int __gthread_objc_thread_exit(void) { ++ thd_exit(NULL); ++ ++ /* Failed if we reached here */ ++ return -1; ++} ++ ++/* Returns an integer value which uniquely describes a thread. */ ++static inline objc_thread_t __gthread_objc_thread_id(void) { ++ return (objc_thread_t)thd_get_current(); ++} ++ ++/* Sets the thread's local storage pointer. */ ++static inline int __gthread_objc_thread_set_data(void *value) { ++ return kthread_setspecific(_objc_thread_storage, value); ++} ++ ++/* Returns the thread's local storage pointer. */ ++static inline void *__gthread_objc_thread_get_data(void) { ++ return kthread_getspecific(_objc_thread_storage); ++} ++ ++/* Backend mutex functions */ ++ ++/* Allocate a mutex. */ ++static inline int __gthread_objc_mutex_allocate(objc_mutex_t mutex) { ++ mutex_t *m = mutex_create(); ++ ++ if(m) { ++ mutex->backend = (void *)m; ++ return 0; ++ } ++ ++ mutex->backend = NULL; ++ return -1; ++} ++ ++/* Deallocate a mutex. */ ++static inline int __gthread_objc_mutex_deallocate(objc_mutex_t mutex) { ++ mutex_t *m = (mutex_t *)mutex->backend; ++ ++ if(mutex_is_locked(m)) { ++ mutex_unlock(m); ++ } ++ ++ mutex_destroy(m); ++ mutex->backend = NULL; ++ ++ return 0; ++} ++ ++/* Grab a lock on a mutex. */ ++static inline int __gthread_objc_mutex_lock(objc_mutex_t mutex) { ++ return mutex_lock((mutex_t *)mutex->backend); ++} ++ ++/* Try to grab a lock on a mutex. */ ++static inline int __gthread_objc_mutex_trylock(objc_mutex_t mutex) { ++ return mutex_trylock((mutex_t *)mutex->backend); ++} ++ ++/* Unlock the mutex. */ ++static inline int __gthread_objc_mutex_unlock(objc_mutex_t mutex) { ++ mutex_unlock((mutex_t *)mutex->backend); ++ return 0; ++} ++ ++/* Backend condition mutex functions */ ++ ++/* Allocate a condition. */ ++static inline int __gthread_objc_condition_allocate(objc_condition_t cond) { ++ condvar_t *c = cond_create(); ++ ++ if(c) { ++ cond->backend = (void *)c; ++ return 0; ++ } ++ ++ cond->backend = NULL; ++ return -1; ++} ++ ++/* Deallocate a condition. */ ++static inline int __gthread_objc_condition_deallocate(objc_condition_t cond) { ++ cond_destroy((condvar_t *)cond->backend); ++ cond->backend = NULL; ++ return 0; ++} ++ ++/* Wait on the condition. */ ++static inline int __gthread_objc_condition_wait(objc_condition_t cond, ++ objc_mutex_t mutex) { ++ return cond_wait((condvar_t *)cond->backend, (mutex_t *)mutex->backend); ++} ++ ++/* Wake up all threads waiting on this condition. */ ++static inline int __gthread_objc_condition_broadcast(objc_condition_t cond) { ++ cond_broadcast((condvar_t *)cond->backend); ++ return 0; ++} ++ ++/* Wake up one thread waiting on this condition. */ ++static inline int __gthread_objc_condition_signal(objc_condition_t cond) { ++ cond_signal((condvar_t *)cond->backend); ++ return 0; ++} ++ ++#else /* _LIBOBJC */ ++ ++static inline int __gthread_once(__gthread_once_t *__once, ++ void (*__func)(void)) { ++ return kthread_once(__once, __func); ++} ++ ++static inline int __gthread_key_create(__gthread_key_t *__key, ++ void (*__func)(void *)) { ++ return kthread_key_create(__key, __func); ++} ++ ++static int __gthread_key_delete(__gthread_key_t __key) { ++ return kthread_key_delete(__key); ++} ++ ++static inline void *__gthread_getspecific(__gthread_key_t __key) { ++ return kthread_getspecific(__key); ++} ++ ++static inline int __gthread_setspecific(__gthread_key_t __key, ++ const void *__v) { ++ return kthread_setspecific(__key, __v); ++} ++ ++static inline int __gthread_mutex_destroy(__gthread_mutex_t *__mutex) { ++ assert(__mutex); ++ mutex_destroy(*__mutex); ++ return 0; ++} ++ ++static inline int __gthread_mutex_lock(__gthread_mutex_t *__mutex) { ++ assert(__mutex); ++ return mutex_lock(*__mutex); ++} ++ ++static inline int __gthread_mutex_trylock(__gthread_mutex_t *__mutex) { ++ assert(__mutex); ++ return mutex_trylock(*__mutex); ++} ++ ++static inline int __gthread_mutex_unlock(__gthread_mutex_t *__mutex) { ++ assert(__mutex); ++ mutex_unlock(*__mutex); ++ return 0; ++} ++ ++static inline int __gthread_recursive_mutex_lock(__gthread_recursive_mutex_t *__mutex) { ++ assert(__mutex); ++ return rlock_lock(*__mutex); ++} ++ ++static inline int __gthread_recursive_mutex_trylock(__gthread_recursive_mutex_t *__mutex) { ++ assert(__mutex); ++ return rlock_trylock(*__mutex); ++} ++ ++static inline int __gthread_recursive_mutex_unlock(__gthread_recursive_mutex_t *__mutex) { ++ assert(__mutex); ++ return rlock_unlock(*__mutex); ++} ++ ++static inline int __gthread_cond_broadcast(__gthread_cond_t *cond) { ++ assert(cond); ++ cond_broadcast(*cond); ++ return 0; ++} ++ ++static inline int __gthread_cond_wait(__gthread_cond_t *cond, __gthread_mutex_t *mutex) { ++ assert(cond); ++ return cond_wait(*cond, *mutex); ++} ++ ++static inline int __gthread_cond_wait_recursive(__gthread_cond_t *cond, ++ __gthread_recursive_mutex_t *mutex) { ++ assert(cond); ++ return cond_wait_recursive(*cond, *mutex); ++} ++ ++/* C++0x support functions */ ++ ++static inline int __gthread_create(__gthread_t *thd, void *(*func)(void *), ++ void *args) { ++ assert(thd); ++ *thd = thd_create(0, func, args); ++ return (*thd == NULL); ++} ++ ++static inline int __gthread_join(__gthread_t thd, void **value_ptr) { ++ assert(thd); ++ return thd_join(thd, value_ptr); ++} ++ ++static inline int __gthread_detach(__gthread_t thd) { ++ assert(thd); ++ return thd_detach(thd); ++} ++ ++static inline int __gthread_equal(__gthread_t t1, __gthread_t t2) { ++ return t1 == t2; ++} ++ ++static inline __gthread_t __gthread_self(void) { ++ return thd_get_current(); ++} ++ ++static inline int __gthread_yield(void) { ++ thd_pass(); ++ return 0; ++} ++ ++static inline int __gthread_mutex_timedlock(__gthread_mutex_t *m, ++ const __gthread_time_t *timeout) { ++ int t = (int)(timeout->tv_sec + (timeout->tv_nsec / 1000)); ++ assert(m); ++ return mutex_lock_timed(*m, t); ++} ++ ++static inline int __gthread_recursive_mutex_timedlock(__gthread_recursive_mutex_t *l, ++ const __gthread_time_t *timeout) { ++ int t = (int)(timeout->tv_sec + (timeout->tv_nsec / 1000)); ++ assert(l); ++ return rlock_lock_timed(*l, t); ++} ++ ++static inline int __gthread_cond_signal(__gthread_cond_t *cond) { ++ assert(cond); ++ cond_signal(*cond); ++ return 0; ++} ++ ++static inline int __gthread_cond_timedwait(__gthread_cond_t *cond, ++ __gthread_mutex_t *mutex, ++ const __gthread_time_t *timeout) { ++ int t = (int)(timeout->tv_sec + (timeout->tv_nsec / 1000)); ++ assert(cond); ++ return cond_wait_timed(*cond, *mutex, t); ++} ++ ++static inline int __gthread_cond_timedwait_recursive(__gthread_cond_t *cond, ++ __gthread_recursive_mutex_t *l, ++ const __gthread_time_t *timeout) { ++ int t = (int)(timeout->tv_sec + (timeout->tv_nsec / 1000)); ++ assert(cond); ++ return cond_wait_timed_recursive(*cond, *l, t); ++} ++ ++#endif /* _LIBOBJC */ ++ ++#endif /* ! GCC_GTHR_KOS_H */ Added: kos/utils/dc-chain/patches/newlib-1.19.0-kos.diff =================================================================== --- kos/utils/dc-chain/patches/newlib-1.19.0-kos.diff (rev 0) +++ kos/utils/dc-chain/patches/newlib-1.19.0-kos.diff 2011-01-09 04:53:55 UTC (rev 699) @@ -0,0 +1,487 @@ +diff -ruN newlib-1.19.0-orig/newlib/configure.host newlib-1.19.0/newlib/configure.host +--- newlib-1.19.0-orig/newlib/configure.host 2010-12-02 14:30:46.000000000 -0500 ++++ newlib-1.19.0/newlib/configure.host 2011-01-08 00:28:36.000000000 -0500 +@@ -234,6 +234,7 @@ + ;; + sh | sh64) + machine_dir=sh ++ newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED -DMALLOC_PROVIDED -DABORT_PROVIDED -fno-crossjumping -fno-optimize-sibling-calls" + ;; + sparc*) + machine_dir=sparc +diff -ruN newlib-1.19.0-orig/newlib/libc/include/assert.h newlib-1.19.0/newlib/libc/include/assert.h +--- newlib-1.19.0-orig/newlib/libc/include/assert.h 2008-07-17 16:56:51.000000000 -0400 ++++ newlib-1.19.0/newlib/libc/include/assert.h 2011-01-08 01:26:09.000000000 -0500 +@@ -13,8 +13,8 @@ + #ifdef NDEBUG /* required by ANSI standard */ + # define assert(__e) ((void)0) + #else +-# define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ +- __ASSERT_FUNC, #__e)) ++# define assert(__e) ((__e) ? (void)0 : __assert (__FILE__, __LINE__, \ ++ #__e, (char *)0, __ASSERT_FUNC)) + + # ifndef __ASSERT_FUNC + /* Use g++'s demangled names in C++. */ +@@ -36,10 +36,8 @@ + # endif /* !__ASSERT_FUNC */ + #endif /* !NDEBUG */ + +-void _EXFUN(__assert, (const char *, int, const char *) +- _ATTRIBUTE ((__noreturn__))); +-void _EXFUN(__assert_func, (const char *, int, const char *, const char *) +- _ATTRIBUTE ((__noreturn__))); ++void _EXFUN(__assert, (const char *, int, const char *, const char *, ++ const char *) _ATTRIBUTE ((__noreturn__))); + + #ifdef __cplusplus + } +diff -ruN newlib-1.19.0-orig/newlib/libc/include/sys/types.h newlib-1.19.0/newlib/libc/include/sys/types.h +--- newlib-1.19.0-orig/newlib/libc/include/sys/types.h 2010-12-08 09:44:06.000000000 -0500 ++++ newlib-1.19.0/newlib/libc/include/sys/types.h 2011-01-08 00:10:45.000000000 -0500 +@@ -282,7 +282,7 @@ + + #if defined(__XMK__) + typedef unsigned int pthread_t; /* identify a thread */ +-#else ++#elif !defined(_arch_dreamcast) + typedef __uint32_t pthread_t; /* identify a thread */ + #endif + +@@ -333,6 +333,7 @@ + + #endif /* defined(__XMK__) || defined(__rtems__) */ + ++#ifndef _arch_dreamcast + #if defined(__XMK__) + typedef struct pthread_attr_s { + int contentionscope; +@@ -366,6 +367,7 @@ + } pthread_attr_t; + + #endif /* !defined(__XMK__) */ ++#endif + + #if defined(_POSIX_THREAD_PROCESS_SHARED) + /* NOTE: P1003.1c/D10, p. 81 defines following values for process_shared. */ +@@ -405,6 +407,7 @@ + } pthread_mutexattr_t; + + #else /* !defined(__XMK__) */ ++#ifndef _arch_dreamcast + typedef __uint32_t pthread_mutex_t; /* identify a mutex */ + + typedef struct { +@@ -421,10 +424,12 @@ + #endif + int recursive; + } pthread_mutexattr_t; ++#endif /* !_arch_dreamcast */ + #endif /* !defined(__XMK__) */ + + /* Condition Variables */ + ++#ifndef _arch_dreamcast + typedef __uint32_t pthread_cond_t; /* identify a condition variable */ + + typedef struct { +@@ -433,15 +438,18 @@ + int process_shared; /* allow this to be shared amongst processes */ + #endif + } pthread_condattr_t; /* a condition attribute object */ ++#endif + + /* Keys */ + ++#ifndef _arch_dreamcast + typedef __uint32_t pthread_key_t; /* thread-specific data keys */ + + typedef struct { + int is_initialized; /* is this structure initialized? */ + int init_executed; /* has the initialization routine been run? */ + } pthread_once_t; /* dynamic package initialization */ ++#endif + #else + #if defined (__CYGWIN__) + #include <cygwin/types.h> +diff -ruN newlib-1.19.0-orig/newlib/libc/stdlib/assert.c newlib-1.19.0/newlib/libc/stdlib/assert.c +--- newlib-1.19.0-orig/newlib/libc/stdlib/assert.c 2009-10-08 12:44:10.000000000 -0400 ++++ newlib-1.19.0/newlib/libc/stdlib/assert.c 2011-01-08 00:29:47.000000000 -0500 +@@ -47,6 +47,8 @@ + #include <stdlib.h> + #include <stdio.h> + ++#if 0 ++ + #ifndef HAVE_ASSERT_FUNC + /* func can be NULL, in which case no function information is given. */ + void +@@ -74,3 +76,4 @@ + __assert_func (file, line, NULL, failedexpr); + /* NOTREACHED */ + } ++#endif +diff -ruN newlib-1.19.0-orig/newlib/libc/sys/sh/ftruncate.c newlib-1.19.0/newlib/libc/sys/sh/ftruncate.c +--- newlib-1.19.0-orig/newlib/libc/sys/sh/ftruncate.c 2003-07-10 11:31:30.000000000 -0400 ++++ newlib-1.19.0/newlib/libc/sys/sh/ftruncate.c 2011-01-08 00:12:11.000000000 -0500 +@@ -2,8 +2,8 @@ + #include <sys/types.h> + #include "sys/syscall.h" + +-int ++/* int + ftruncate (int file, off_t length) + { + return __trap34 (SYS_ftruncate, file, length, 0); +-} ++} */ +diff -ruN newlib-1.19.0-orig/newlib/libc/sys/sh/sys/lock.h newlib-1.19.0/newlib/libc/sys/sh/sys/lock.h +--- newlib-1.19.0-orig/newlib/libc/sys/sh/sys/lock.h 1969-12-31 19:00:00.000000000 -0500 ++++ newlib-1.19.0/newlib/libc/sys/sh/sys/lock.h 2011-01-08 00:15:28.000000000 -0500 +@@ -0,0 +1,51 @@ ++/* KallistiOS ##version## ++ ++ lock_common.h ++ Copyright (C)2004 Dan Potter ++ ++*/ ++ ++#ifndef __SYS_LOCK_H__ ++#define __SYS_LOCK_H__ ++ ++typedef struct { ++ void * owner; ++ int nest; ++ volatile int lock; ++} __newlib_recursive_lock_t; ++ ++#define __NEWLIB_RECURSIVE_LOCK_INIT { (void *)0, 0, 0 } ++ ++typedef volatile int __newlib_lock_t; ++#define __NEWLIB_LOCK_INIT 0 ++ ++typedef __newlib_lock_t _LOCK_T; ++typedef __newlib_recursive_lock_t _LOCK_RECURSIVE_T; ++ ++#define __LOCK_INIT(class,lock) class _LOCK_T lock = __NEWLIB_LOCK_INIT; ++#define __LOCK_INIT_RECURSIVE(class,lock) class _LOCK_RECURSIVE_T lock = __NEWLIB_RECURSIVE_LOCK_INIT; ++#define __lock_init(lock) __newlib_lock_init(&(lock)) ++#define __lock_init_recursive(lock) __newlib_lock_init_recursive(&(lock)) ++#define __lock_close(lock) __newlib_lock_close(&(lock)) ++#define __lock_close_recursive(lock) __newlib_lock_close_recursive(&(lock)) ++#define __lock_acquire(lock) __newlib_lock_acquire(&(lock)) ++#define __lock_acquire_recursive(lock) __newlib_lock_acquire_recursive(&(lock)) ++#define __lock_try_acquire(lock) __newlib_lock_try_acquire(&(lock)) ++#define __lock_try_acquire_recursive(lock) __newlib_lock_try_acquire_recursive(&(lock)) ++#define __lock_release(lock) __newlib_lock_release(&(lock)) ++#define __lock_release_recursive(lock) __newlib_lock_release_recursive(&(lock)) ++ ++void __newlib_lock_init(__newlib_lock_t *); ++void __newlib_lock_close(__newlib_lock_t *); ++void __newlib_lock_acquire(__newlib_lock_t *); ++void __newlib_lock_try_acquire(__newlib_lock_t *); ++void __newlib_lock_release(__newlib_lock_t *); ++ ++void __newlib_lock_init_recursive(__newlib_recursive_lock_t *); ++void __newlib_lock_close_recursive(__newlib_recursive_lock_t *); ++void __newlib_lock_acquire_recursive(__newlib_recursive_lock_t *); ++void __newlib_lock_try_acquire_recursive(__newlib_recursive_lock_t *); ++void __newlib_lock_release_recursive(__newlib_recursive_lock_t *); ++ ++ ++#endif // __NEWLIB_LOCK_COMMON_H +diff -ruN newlib-1.19.0-orig/newlib/libc/sys/sh/syscalls.c newlib-1.19.0/newlib/libc/sys/sh/syscalls.c +--- newlib-1.19.0-orig/newlib/libc/sys/sh/syscalls.c 2008-01-21 19:24:45.000000000 -0500 ++++ newlib-1.19.0/newlib/libc/sys/sh/syscalls.c 2011-01-08 00:12:55.000000000 -0500 +@@ -1,228 +1,2 @@ +-#include <_ansi.h> +-#include <sys/types.h> +-#include <sys/stat.h> +-#include <sys/time.h> +-#include "sys/syscall.h" +-int errno; +- +-/* This is used by _sbrk. */ +-register char *stack_ptr asm ("r15"); +- +-int +-_read (int... [truncated message content] |
From: <ljs...@us...> - 2010-12-28 03:35:17
|
Revision: 698 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=698&view=rev Author: ljsebald Date: 2010-12-28 03:35:11 +0000 (Tue, 28 Dec 2010) Log Message: ----------- Fixup kos-ports for the new threading stuff (so everything compiles again). Modified Paths: -------------- kos-ports/SDL/base/src/thread/dc/SDL_systhread.c kos-ports/libconio/conio.c kos-ports/libmp3/libmp3/main.c kos-ports/liboggvorbis/liboggvorbisplay/main.c kos-ports/libtremor/kos/main.c kos-ports/lwip/kos/netif/kosnetif.c kos-ports/lwip/kos/sys_arch.c Modified: kos-ports/SDL/base/src/thread/dc/SDL_systhread.c =================================================================== --- kos-ports/SDL/base/src/thread/dc/SDL_systhread.c 2010-12-28 03:19:51 UTC (rev 697) +++ kos-ports/SDL/base/src/thread/dc/SDL_systhread.c 2010-12-28 03:35:11 UTC (rev 698) @@ -61,9 +61,15 @@ } #else +static void *thdfunc(void *args) +{ + SDL_RunThread(args); + return NULL; +} + int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) { - thread->handle = thd_create(SDL_RunThread,args); + thread->handle = thd_create(1, thdfunc, args); if (thread->handle == NULL) { SDL_SetError("Not enough resources to create thread"); return(-1); @@ -83,7 +89,7 @@ void SDL_SYS_WaitThread(SDL_Thread *thread) { - thd_wait(thread->handle); + thd_join(thread->handle, NULL); } void SDL_SYS_KillThread(SDL_Thread *thread) Modified: kos-ports/libconio/conio.c =================================================================== --- kos-ports/libconio/conio.c 2010-12-28 03:19:51 UTC (rev 697) +++ kos-ports/libconio/conio.c 2010-12-28 03:35:11 UTC (rev 698) @@ -352,7 +352,7 @@ static volatile int conio_exit = 0; /* the drawing/keyboard polling thread */ -static void conio_thread(void *param) { +static void *conio_thread(void *param) { conio_entered = 1; while (!conio_exit) { sem_wait(ft_mutex); @@ -369,6 +369,7 @@ sem_signal(ft_mutex); } conio_exit = -1; + return NULL; } /* initialize the console I/O stuffs */ @@ -406,7 +407,7 @@ /* create the conio thread */ conio_exit = 0; - if (thd_create(conio_thread, 0) < 0) + if (thd_create(1, conio_thread, 0) < 0) return -1; /* Wait for it to actually start */ Modified: kos-ports/libmp3/libmp3/main.c =================================================================== --- kos-ports/libmp3/libmp3/main.c 2010-12-28 03:19:51 UTC (rev 697) +++ kos-ports/libmp3/libmp3/main.c 2010-12-28 03:35:11 UTC (rev 698) @@ -7,20 +7,20 @@ #include <kos.h> -int sndserver_thread(void *blagh) { +void *sndserver_thread(void *blagh) { printf("sndserver: started [DEBUG]\r\n"); printf("sndserver: pid is %d; capabilities: MP3, SFX\r\n", thd_get_current()->tid); sndmp3_mainloop(); printf("sndserver exited\r\n"); - return 0; + return NULL; } int mp3_init() { if (snd_stream_init() < 0) return -1; - if (thd_create(sndserver_thread, NULL) != NULL) { + if (thd_create(1, sndserver_thread, NULL) != NULL) { sndmp3_wait_start(); return 0; } else Modified: kos-ports/liboggvorbis/liboggvorbisplay/main.c =================================================================== --- kos-ports/liboggvorbis/liboggvorbisplay/main.c 2010-12-28 03:19:51 UTC (rev 697) +++ kos-ports/liboggvorbis/liboggvorbisplay/main.c 2010-12-28 03:35:11 UTC (rev 698) @@ -2,9 +2,10 @@ static kthread_t * thd = NULL; -static void sndserver_thread(void *blagh) { +static void *sndserver_thread(void *blagh) { printf("sndserver: pid is %d\n", thd_get_current()->tid); sndoggvorbis_mainloop(); + return NULL; } int sndoggvorbis_init() { @@ -17,7 +18,7 @@ return -1; printf("sndserver: initializing sndoggvorbis 0.7 [OggVorbis 1.0 based]\n"); - thd = thd_create(sndserver_thread, NULL); + thd = thd_create(0, sndserver_thread, NULL); if (thd != NULL) { /* Wait until the oggvorbis decoder thread is ready */ sndoggvorbis_wait_start(); @@ -38,7 +39,7 @@ } sndoggvorbis_thd_quit(); - thd_wait(thd); + thd_join(thd, NULL); thd = NULL; printf("sndserver: exited successfully\n"); Modified: kos-ports/libtremor/kos/main.c =================================================================== --- kos-ports/libtremor/kos/main.c 2010-12-28 03:19:51 UTC (rev 697) +++ kos-ports/libtremor/kos/main.c 2010-12-28 03:35:11 UTC (rev 698) @@ -2,9 +2,10 @@ static kthread_t * thd = NULL; -static void sndserver_thread(void *blagh) { +static void *sndserver_thread(void *blagh) { printf("sndserver: pid is %d\n", thd_get_current()->tid); sndoggvorbis_mainloop(); + return NULL; } int sndoggvorbis_init() { @@ -17,7 +18,7 @@ return -1; printf("sndserver: initializing libtremor 1.0 [Tremor 20020902 based]\n"); - thd = thd_create(sndserver_thread, NULL); + thd = thd_create(0, sndserver_thread, NULL); if (thd != NULL) { /* Wait until the oggvorbis decoder thread is ready */ sndoggvorbis_wait_start(); @@ -38,7 +39,7 @@ } sndoggvorbis_thd_quit(); - thd_wait(thd); + thd_join(thd, NULL); thd = NULL; printf("sndserver: exited successfully\n"); Modified: kos-ports/lwip/kos/netif/kosnetif.c =================================================================== --- kos-ports/lwip/kos/netif/kosnetif.c 2010-12-28 03:19:51 UTC (rev 697) +++ kos-ports/lwip/kos/netif/kosnetif.c 2010-12-28 03:35:11 UTC (rev 698) @@ -285,7 +285,7 @@ /* The processing thread. This should ideally run at a better priority than other things to lower latency, but we leave it at normal for now to avoid lockups on bugs. */ -static void kosnetif_thread(void * blegh) { +static void *kosnetif_thread(void * blegh) { struct eth_hdr * ethernet_header; struct pbuf *p, *q; int i; @@ -325,6 +325,8 @@ pbuf_free(q); } } + + return NULL; } /* Called from the driver IRQ handler */ @@ -395,7 +397,7 @@ low_input_init(); for (i=0; i<ETH_THD_CNT; i++) { - eth_thd[i] = thd_create(kosnetif_thread, NULL); + eth_thd[i] = thd_create(0, kosnetif_thread, NULL); // thd_set_prio(eth_thd[i], PRIO_DEFAULT-2); } oldfunc = net_input_set_target(knet_input_low); @@ -417,7 +419,7 @@ sem_signal(wait_p); } for (i=0; i<ETH_THD_CNT; i++) - thd_wait(eth_thd[i]); + thd_join(eth_thd[i], NULL); low_input_shutdown(); netif = NULL; Modified: kos-ports/lwip/kos/sys_arch.c =================================================================== --- kos-ports/lwip/kos/sys_arch.c 2010-12-28 03:19:51 UTC (rev 697) +++ kos-ports/lwip/kos/sys_arch.c 2010-12-28 03:35:11 UTC (rev 698) @@ -61,7 +61,7 @@ } /* Threads will start and end here */ -static void thread_start(void *arg) { +static void *thread_start(void *arg) { struct sys_thread * tp = (struct sys_thread *)arg; tp->function(tp->arg); @@ -71,6 +71,7 @@ mutex_unlock(threads_mutex); free(tp); + return NULL; } sys_thread_t sys_thread_new(void (* function)(void *arg), void *arg, int prio) { @@ -89,7 +90,7 @@ thread->function = function; thread->arg = arg; - thread->thd = thd_create(thread_start, thread); + thread->thd = thd_create(1, thread_start, thread); //thd_set_prio(thread->thd, PRIO_DEFAULT - 1); assert_msg(thread->thd != NULL, "Couldn't create a new lwIP thread"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2010-12-28 03:19:58
|
Revision: 697 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=697&view=rev Author: ljsebald Date: 2010-12-28 03:19:51 +0000 (Tue, 28 Dec 2010) Log Message: ----------- Fix up a few more examples that use threads so that the new thread stuff doesn't cause problems with them directly. Modified Paths: -------------- kos/examples/dreamcast/network/httpd/httpd.c kos/examples/dreamcast/network/httpd/simhost.c kos/examples/dreamcast/sound/ghettoplay-vorbis/songmenu.c Modified: kos/examples/dreamcast/network/httpd/httpd.c =================================================================== --- kos/examples/dreamcast/network/httpd/httpd.c 2010-12-28 03:09:03 UTC (rev 696) +++ kos/examples/dreamcast/network/httpd/httpd.c 2010-12-28 03:19:51 UTC (rev 697) @@ -207,7 +207,7 @@ #define BUFSIZE (256*1024) -void client_thread(void *p) { +void *client_thread(void *p) { http_state_t * hs = (http_state_t *)p; char * buf, * ext; const char * ct; @@ -277,6 +277,7 @@ st_destroy(hs); if (f >= 0) fs_close(f); + return NULL; } /**********************************************************************/ @@ -361,7 +362,7 @@ if (hs->socket < 0) { st_destroy(hs); } else { - hs->thd = thd_create(client_thread, hs); + hs->thd = thd_create(1, client_thread, hs); // hs->thd = sys_thread_new(client_thread, hs, 0); } /* else if (ioctl(hs->socket, FIONBIO, &tmp) < 0) { Modified: kos/examples/dreamcast/network/httpd/simhost.c =================================================================== --- kos/examples/dreamcast/network/httpd/simhost.c 2010-12-28 03:09:03 UTC (rev 696) +++ kos/examples/dreamcast/network/httpd/simhost.c 2010-12-28 03:19:51 UTC (rev 697) @@ -6,14 +6,15 @@ KOS_INIT_ROMDISK(romdisk); void httpd(); -void do_httpd(void * foo) { +void *do_httpd(void * foo) { httpd(); + return NULL; } int main(int argc, char **argv) { net_init(); lwip_kos_init(); - thd_create(do_httpd, NULL); + thd_create(1, do_httpd, NULL); vid_clear(50,0,70); bfont_draw_str(vram_s + 20*640+20, 640, 0, "KOSHttpd active"); Modified: kos/examples/dreamcast/sound/ghettoplay-vorbis/songmenu.c =================================================================== --- kos/examples/dreamcast/sound/ghettoplay-vorbis/songmenu.c 2010-12-28 03:09:03 UTC (rev 696) +++ kos/examples/dreamcast/sound/ghettoplay-vorbis/songmenu.c 2010-12-28 03:19:51 UTC (rev 697) @@ -104,7 +104,7 @@ } -static void load_song_list(void * p) { +static void *load_song_list(void * p) { file_t d; d = fs_open(curdir, O_RDONLY | O_DIR); @@ -117,7 +117,7 @@ strcpy(entries[0].fn,"Error!"); entries[0].size = 0; mutex_unlock(mut); - return; + return NULL; } } { @@ -142,6 +142,7 @@ } fs_close(d); load_queued = 0; + return NULL; } /* Draws the song listing */ @@ -406,7 +407,7 @@ /* If we don't have a file listing, get it now */ if (num_entries == 0 && !load_queued) { load_queued = 1; - thd_create(load_song_list, NULL); + thd_create(1, load_song_list, NULL); } /* if (load_queued) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2010-12-28 03:09:09
|
Revision: 696 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=696&view=rev Author: ljsebald Date: 2010-12-28 03:09:03 +0000 (Tue, 28 Dec 2010) Log Message: ----------- Fix threading examples so they comply with the new threading system. Modified Paths: -------------- kos/examples/dreamcast/basic/threading/general/general_threading_test.c kos/examples/dreamcast/basic/threading/once/once_test.c kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c kos/examples/dreamcast/basic/threading/tls/tls_test.c Modified: kos/examples/dreamcast/basic/threading/general/general_threading_test.c =================================================================== --- kos/examples/dreamcast/basic/threading/general/general_threading_test.c 2010-12-27 04:04:30 UTC (rev 695) +++ kos/examples/dreamcast/basic/threading/general/general_threading_test.c 2010-12-28 03:09:03 UTC (rev 696) @@ -18,7 +18,7 @@ semaphore_t *sem; /* This routine will be started as thread #0 */ -void thd_0(void *v) { +void *thd_0(void *v) { int x, y; printf("Thread 0 started\n"); @@ -26,10 +26,11 @@ for (x=0; x<320; x++) vram_s[y*640+x] = (((x*x) + (y*y)) & 0x1f) << 11; printf("Thread 0 finished\n"); + return NULL; } /* This routine will be started as thread #1 */ -void thd_1(void *v) { +void *thd_1(void *v) { int i; for (i=0; i<30; i++) { @@ -40,10 +41,11 @@ printf("Thread 1 waiting:\n"); thd_sleep(5000); printf("Thread 1 exiting\n"); + return NULL; } /* This routine will be started as thread #2 */ -void thd_2(void *v) { +void *thd_2(void *v) { int i; thd_sleep(50); @@ -55,6 +57,7 @@ printf("sem_wait_timed returns %d\n", sem_wait_timed(sem, 200)); printf("sem_wait_timed returns %d\n", sem_wait_timed(sem, 200)); printf("Thread 2 exiting\n"); + return NULL; } /* Condvar/mutex used for timing below */ @@ -63,7 +66,7 @@ volatile int cv_ready = 0, cv_cnt = 0, cv_quit = 0; /* This routine will be started N times for the condvar testing */ -void thd_3(void *v) { +void *thd_3(void *v) { printf("Thread %d started\n", (int)v); mutex_lock(mut); @@ -83,6 +86,7 @@ mutex_unlock(mut); printf("Thread %d exiting\n", (int)v); + return NULL; } /* Hardware / basic OS init: IRQs disabled, threads enabled, @@ -94,17 +98,20 @@ int x, y, i; kthread_t * t0, * t1, * t2, *t3[10]; - cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, arch_exit); + cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, + (cont_btn_callback_t)arch_exit); /* Print a banner */ printf("KOS 1.1.x thread program:\n"); /* Create two threads, but don't start them yet. Note that at this point in your program, IRQs are still disabled. This is so that you - have full control over what happens to the threads. */ - t0 = thd_create(thd_0, NULL); - t1 = thd_create(thd_1, NULL); - t2 = thd_create(thd_2, NULL); + have full control over what happens to the threads. All threads are + created as joinable so we can thd_join them later on to wait for them + to die. */ + t0 = thd_create(0, thd_0, NULL); + t1 = thd_create(0, thd_1, NULL); + t2 = thd_create(0, thd_2, NULL); /* Create a semaphore for timing purposes */ sem = sem_create(1); @@ -121,10 +128,10 @@ thd_pslist_queue(printf); printf("Waiting for the death of thread 1:\n"); - x = thd_wait(t1); + x = thd_join(t1, NULL); printf("Retval was %d. Waiting for the death of thread 2:\n", x); - x = thd_wait(t2); + x = thd_join(t2, NULL); printf("Retval was %d.\n", x); printf("Testing idle sleeping:\n"); @@ -132,15 +139,15 @@ thd_sleep(1000); printf("Test succeeded\n"); - thd_wait(t0); + thd_join(t0, NULL); printf("\n\nCondvar test; starting threads\n"); - printf("Main thread is %08lx\n", thd_current); + printf("Main thread is %p\n", thd_current); mut = mutex_create(); cv = cond_create(); for (i=0; i<10; i++) { - t3[i] = thd_create(thd_3, (void *)i); - printf("Thread %d is %08lx\n", i, t3[i]); + t3[i] = thd_create(0, thd_3, (void *)i); + printf("Thread %d is %p\n", i, t3[i]); } thd_sleep(500); @@ -179,7 +186,7 @@ cond_broadcast(cv); mutex_unlock(mut); for (i=0; i<10; i++) - thd_wait(t3[i]); + thd_join(t3[i], NULL); /* Disable IRQs, thus turning off threading. All threads that were running are now gone. If your threads were doing anything like Modified: kos/examples/dreamcast/basic/threading/once/once_test.c =================================================================== --- kos/examples/dreamcast/basic/threading/once/once_test.c 2010-12-27 04:04:30 UTC (rev 695) +++ kos/examples/dreamcast/basic/threading/once/once_test.c 2010-12-28 03:09:03 UTC (rev 696) @@ -28,12 +28,13 @@ ++counter; } -void thd_func(void *param UNUSED) { +void *thd_func(void *param UNUSED) { kthread_t *cur = thd_get_current(); printf("Thd %d: Attempting to call kthread_once\n", cur->tid); kthread_once(&once, &once_func); printf("Thd %d: kthread_once returned\n", cur->tid); + return NULL; } KOS_INIT_FLAGS(INIT_DEFAULT); @@ -43,19 +44,19 @@ kthread_t *thds[THD_COUNT]; cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, - arch_exit); + (cont_btn_callback_t)arch_exit); printf("KallistiOS kthread_once test program\n"); /* Create the threads. */ printf("Creating %d threads\n", THD_COUNT); for(i = 0; i < THD_COUNT; ++i) { - thds[i] = thd_create(&thd_func, NULL); + thds[i] = thd_create(0, &thd_func, NULL); } printf("Waiting for the threads to finish\n"); for(i = 0; i < THD_COUNT; ++i) { - thd_wait(thds[i]); + thd_join(thds[i], NULL); } printf("Final counter value: %d (expected 1)\n", counter); Modified: kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c =================================================================== --- kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c 2010-12-27 04:04:30 UTC (rev 695) +++ kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c 2010-12-28 03:09:03 UTC (rev 696) @@ -22,7 +22,7 @@ recursive_lock_t *l = NULL; -void thd0(void *param UNUSED) { +void *thd0(void *param UNUSED) { int i; printf("Thd 0: About to obtain lock 10 times\n"); @@ -47,9 +47,10 @@ printf("Thd 0: Awake, about to release lock\n"); rlock_unlock(l); printf("Thd 0: done\n"); + return NULL; } -void thd1(void *param UNUSED) { +void *thd1(void *param UNUSED) { printf("Thd 1: About to obtain lock 2 times\n"); rlock_lock(l); rlock_lock(l); @@ -67,9 +68,10 @@ printf("Thd 1: About to release lock\n"); rlock_unlock(l); printf("Thd 1: done\n"); + return NULL; } -void thd2(void *param UNUSED) { +void *thd2(void *param UNUSED) { int i; printf("Thd 2: About to obtain lock 200 times\n"); @@ -85,6 +87,7 @@ } printf("Thd 2: done\n"); + return NULL; } KOS_INIT_FLAGS(INIT_DEFAULT); @@ -94,7 +97,7 @@ /* Exit if the user presses all buttons at once. */ cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, - arch_exit); + (cont_btn_callback_t)arch_exit); printf("KallistiOS Recursive Lock test program\n"); @@ -107,14 +110,14 @@ } printf("About to create threads\n"); - t0 = thd_create(thd0, NULL); - t1 = thd_create(thd1, NULL); - t2 = thd_create(thd2, NULL); + t0 = thd_create(0, thd0, NULL); + t1 = thd_create(0, thd1, NULL); + t2 = thd_create(0, thd2, NULL); printf("About to sleep\n"); - thd_wait(t0); - thd_wait(t1); - thd_wait(t2); + thd_join(t0, NULL); + thd_join(t1, NULL); + thd_join(t2, NULL); if(rlock_is_locked(l)) { printf("Lock is still locked!\n"); Modified: kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c =================================================================== --- kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c 2010-12-27 04:04:30 UTC (rev 695) +++ kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c 2010-12-28 03:09:03 UTC (rev 696) @@ -25,13 +25,13 @@ rw_semaphore_t *s = NULL; uint32 number = 0; -void writer0(void *param UNUSED) { +void *writer0(void *param UNUSED) { int i; for(i = 0; i < 20; ++i) { if(rwsem_write_lock(s)) { printf("Writer 0 could not obtain write lock!\n"); - return; + return NULL; } printf("Writer 0 obtained write lock\n"); @@ -42,15 +42,16 @@ } printf("Writer 0 done\n"); + return NULL; } -void writer1(void *param UNUSED) { +void *writer1(void *param UNUSED) { int i; for(i = 0; i < 17; ++i) { if(rwsem_write_lock(s)) { printf("Writer 1 could not obtain write lock!\n"); - return; + return NULL; } printf("Writer 1 obtained write lock\n"); @@ -61,15 +62,16 @@ } printf("Writer 1 done\n"); + return NULL; } -void reader0(void *param UNUSED) { +void *reader0(void *param UNUSED) { int i; for(i = 0; i < 12; ++i) { if(rwsem_read_lock(s)) { printf("Reader 0 could not obtain read lock!\n"); - return; + return NULL; } printf("Reader 0 obtained read lock\n"); @@ -80,15 +82,16 @@ } printf("Reader 0 done\n"); + return NULL; } -void reader1(void *param UNUSED) { +void *reader1(void *param UNUSED) { int i; for(i = 0; i < 23; ++i) { if(rwsem_read_lock(s)) { printf("Reader 1 could not obtain read lock!\n"); - return; + return NULL; } printf("Reader 1 obtained read lock\n"); @@ -99,6 +102,7 @@ } printf("Reader 1 done\n"); + return NULL; } KOS_INIT_FLAGS(INIT_DEFAULT); @@ -107,7 +111,7 @@ /* Exit if the user presses all buttons at once. */ cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, - arch_exit); + (cont_btn_callback_t)arch_exit); printf("KallistiOS Reader/Writer Semaphore test program\n"); @@ -120,16 +124,16 @@ } printf("About to create threads\n"); - w0 = thd_create(writer0, NULL); - w1 = thd_create(writer1, NULL); - r0 = thd_create(reader0, NULL); - r1 = thd_create(reader1, NULL); + w0 = thd_create(0, writer0, NULL); + w1 = thd_create(0, writer1, NULL); + r0 = thd_create(0, reader0, NULL); + r1 = thd_create(0, reader1, NULL); printf("About to sleep\n"); - thd_wait(w0); - thd_wait(w1); - thd_wait(r0); - thd_wait(r1); + thd_join(w0, NULL); + thd_join(w1, NULL); + thd_join(r0, NULL); + thd_join(r1, NULL); if(rwsem_read_lock(s)) { printf("Could not obtain final read lock!\n"); Modified: kos/examples/dreamcast/basic/threading/tls/tls_test.c =================================================================== --- kos/examples/dreamcast/basic/threading/tls/tls_test.c 2010-12-27 04:04:30 UTC (rev 695) +++ kos/examples/dreamcast/basic/threading/tls/tls_test.c 2010-12-28 03:09:03 UTC (rev 696) @@ -32,7 +32,7 @@ } } -void thd_func(void *param UNUSED) { +void *thd_func(void *param UNUSED) { kthread_t *cur = thd_get_current(); void *data; @@ -47,7 +47,7 @@ printf("Thd %d: Writing to key 2\n", cur->tid); if(kthread_setspecific(key2, (void *)cur->tid)) { printf("Error in kthread_setspecific!!!\n"); - thd_exit(); + thd_exit(NULL); } if(cur->tid & 0x01) { @@ -59,6 +59,7 @@ data = kthread_getspecific(key2); printf("Thd %d: kthread_getspecific returned %d (should be %d)\n", cur->tid, (int)data, cur->tid); + return NULL; } KOS_INIT_FLAGS(INIT_DEFAULT); @@ -68,7 +69,7 @@ void *data; cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, - arch_exit); + (cont_btn_callback_t)arch_exit); printf("KallistiOS TLS test program\n"); @@ -85,12 +86,12 @@ /* Create the threads. */ printf("Main therad: Creating 2 threads\n"); - thds[0] = thd_create(&thd_func, NULL); - thds[1] = thd_create(&thd_func, NULL); + thds[0] = thd_create(0, &thd_func, NULL); + thds[1] = thd_create(0, &thd_func, NULL); printf("Main thread: Waiting for the threads to finish\n"); - thd_wait(thds[0]); - thd_wait(thds[1]); + thd_join(thds[0], NULL); + thd_join(thds[1], NULL); data = kthread_getspecific(key1); printf("Main thread: Key 1 value: %p\n", data); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2010-12-27 04:04:37
|
Revision: 695 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=695&view=rev Author: ljsebald Date: 2010-12-27 04:04:30 +0000 (Mon, 27 Dec 2010) Log Message: ----------- Adding in a little bit of a rework of the threading code that I decided to do. This new version has a few nice improvments, namely: 1. No more leaked memory from using stdio in a thread (newlib has a thread cleanup function that is supposed to be called, and now we do that). 2. Zombie cleanup is moved to its own thread, which improves the performance of the scheduling code from O(n) to O(1) on average. 3. Distinguish between detached and joinable threads (as POSIX does). Note that you must either detach a thread or join it to reclaim all resources associated with it now (as in POSIX). Note, I still have to fix up examples and stuff in kos-ports to deal with these changes... Modified Paths: -------------- kos/include/kos/thread.h kos/kernel/arch/dreamcast/hardware/network/broadband_adapter.c kos/kernel/exports.txt kos/kernel/libc/pthreads/pthread_thd.c kos/kernel/net/net_thd.c kos/kernel/thread/thread.c Modified: kos/include/kos/thread.h =================================================================== --- kos/include/kos/thread.h 2010-12-22 15:27:07 UTC (rev 694) +++ kos/include/kos/thread.h 2010-12-27 04:04:30 UTC (rev 695) @@ -1,8 +1,8 @@ /* KallistiOS ##version## include/kos/thread.h - Copyright (C)2000,2001,2002,2003 Dan Potter - Copyright (C) 2009 Lawrence Sebald + Copyright (C) 2000, 2001, 2002, 2003 Dan Potter + Copyright (C) 2009, 2010 Lawrence Sebald */ @@ -109,18 +109,23 @@ /* Thread-local storage */ struct kthread_tls_kv_list tls_list; + + /* Return value of the thread function */ + void *rv; } kthread_t; /* Thread flag values */ -#define THD_DEFAULTS 0 /* Defaults: no flags */ -#define THD_USER 1 /* Thread runs in user mode */ -#define THD_QUEUED 2 /* Thread is in the run queue */ +#define THD_DEFAULTS 0 /* Defaults: no flags */ +#define THD_USER 1 /* Thread runs in user mode */ +#define THD_QUEUED 2 /* Thread is in the run queue */ +#define THD_DETACHED 4 /* Thread is detached */ /* Thread state values */ -#define STATE_ZOMBIE 0x0000 /* Waiting to die */ -#define STATE_RUNNING 0x0001 /* Process is "current" */ -#define STATE_READY 0x0002 /* Ready to be scheduled */ -#define STATE_WAIT 0x0003 /* Blocked on a genwait */ +#define STATE_ZOMBIE 0x0000 /* Waiting to die */ +#define STATE_RUNNING 0x0001 /* Process is "current" */ +#define STATE_READY 0x0002 /* Ready to be scheduled */ +#define STATE_WAIT 0x0003 /* Blocked on a genwait */ +#define STATE_FINISHED 0x0004 /* Finished execution */ /* Are threads cooperative or pre-emptive? */ extern int thd_mode; @@ -132,7 +137,6 @@ extern kthread_t *thd_current; /* "Jiffy" count; just counts context switches */ -/* XXX: Deprecated! */ extern vuint32 jiffies; /* Blocks the calling thread and performs a reschedule as if a context @@ -165,7 +169,7 @@ /* New thread function; given a routine address, it will create a new kernel thread with a default stack. When the routine returns, the thread will exit. Returns the new thread id. */ -kthread_t *thd_create(void (*routine)(void *param), void *param); +kthread_t *thd_create(int detach, void *(*routine)(void *param), void *param); /* Given a thread id, this function removes the thread from the execution chain. */ @@ -173,7 +177,7 @@ /* Thread exit syscall (for use in user-mode processes, but can be used anywhere). */ -void thd_exit() __noreturn; +void thd_exit(void *rv) __noreturn; /* Force a re-schedule; for most cases, you'll want to set front_of_line to zero, but read the comments in kernel/thread/thread.c for more @@ -216,8 +220,11 @@ int thd_set_mode(int mode); /* Wait for a thread to exit */ -int thd_wait(kthread_t * thd); +int thd_join(kthread_t * thd, void **value_ptr); +/* Detach a joinable thread */ +int thd_detach(kthread_t *thd); + /* Print a list of all threads using the given print function. */ int thd_pslist(int (*pf)(const char *fmt, ...)); Modified: kos/kernel/arch/dreamcast/hardware/network/broadband_adapter.c =================================================================== --- kos/kernel/arch/dreamcast/hardware/network/broadband_adapter.c 2010-12-22 15:27:07 UTC (rev 694) +++ kos/kernel/arch/dreamcast/hardware/network/broadband_adapter.c 2010-12-27 04:04:30 UTC (rev 695) @@ -708,7 +708,7 @@ } static int bcolor; -static void bba_rx_threadfunc(void *dummy) { +static void *bba_rx_threadfunc(void *dummy) { while (!bba_rx_exit_thread) { //sem_wait_timed(bba_rx_sema, 500); sem_wait(bba_rx_sema); @@ -733,6 +733,7 @@ bba_rx_exit_thread = 0; printf("bba_rx_thread exiting ...\n"); + return NULL; } static void bba_rx() { @@ -925,7 +926,7 @@ assert( bba_rx_thread == NULL ); bba_rx_sema = sem_create(0); bba_rx_sema2 = sem_create(1); - bba_rx_thread = thd_create(bba_rx_threadfunc, 0); + bba_rx_thread = thd_create(0, bba_rx_threadfunc, 0); bba_rx_thread->prio = 1; thd_set_label(bba_rx_thread, "BBA-rx-thd"); @@ -956,7 +957,7 @@ bba_rx_exit_thread = 1; sem_signal(bba_rx_sema); sem_signal(bba_rx_sema2); - thd_wait(bba_rx_thread); + thd_join(bba_rx_thread, NULL); sem_destroy(bba_rx_sema); sem_destroy(bba_rx_sema2); Modified: kos/kernel/exports.txt =================================================================== --- kos/kernel/exports.txt 2010-12-22 15:27:07 UTC (rev 694) +++ kos/kernel/exports.txt 2010-12-27 04:04:30 UTC (rev 695) @@ -139,7 +139,8 @@ thd_schedule_next thd_sleep thd_pass -thd_wait +thd_join +thd_detach thd_get_label thd_set_label thd_get_current Modified: kos/kernel/libc/pthreads/pthread_thd.c =================================================================== --- kos/kernel/libc/pthreads/pthread_thd.c 2010-12-22 15:27:07 UTC (rev 694) +++ kos/kernel/libc/pthreads/pthread_thd.c 2010-12-27 04:04:30 UTC (rev 695) @@ -12,7 +12,7 @@ assert( thread ); assert( start_routine ); - nt = thd_create( (void (*)(void *))start_routine, arg ); + nt = thd_create(0, start_routine, arg); if (nt) { *thread = nt; return 0; @@ -26,8 +26,7 @@ int pthread_join(pthread_t thread, void **value_ptr) { assert( thread ); - // XXX Need to get return value if value_ptr != NULL. - if (thd_wait(thread) < 0) + if (thd_join(thread, value_ptr) < 0) return ESRCH; else return 0; @@ -36,15 +35,23 @@ /* Detaching a Thread, P1003.1c/Draft 10, p. 149 */ int pthread_detach(pthread_t thread) { - // Currently meaningless. - return 0; + int rv = thd_detach(thread); + + if(rv == -3) { + return EINVAL; + } + else if(rv < 0) { + return ESRCH; + } + else { + return 0; + } } /* Thread Termination, p1003.1c/Draft 10, p. 150 */ void pthread_exit(void *value_ptr) { - // XXX Need to get return value. - thd_exit(); + thd_exit(value_ptr); } /* Get Calling Thread's ID, p1003.1c/Draft 10, p. XXX */ Modified: kos/kernel/net/net_thd.c =================================================================== --- kos/kernel/net/net_thd.c 2010-12-22 15:27:07 UTC (rev 694) +++ kos/kernel/net/net_thd.c 2010-12-27 04:04:30 UTC (rev 695) @@ -30,7 +30,7 @@ static int done = 0; static int cbid_top; -static void net_thd_thd(void *data __attribute__((unused))) { +static void *net_thd_thd(void *data __attribute__((unused))) { struct thd_cb *cb; uint64 now; @@ -48,6 +48,8 @@ /* Go to sleep til we need to be run again. */ thd_sleep(50); } + + return NULL; } int net_thd_add_callback(void (*cb)(void *), void *data, uint64 timeout) { @@ -107,7 +109,7 @@ done = 0; cbid_top = 1; - thd = thd_create(&net_thd_thd, NULL); + thd = thd_create(0, &net_thd_thd, NULL); return 0; } @@ -117,7 +119,7 @@ /* Kill the thread. */ done = 1; - thd_wait(thd); + thd_join(thd, NULL); /* Free any handlers that we have laying around */ c = TAILQ_FIRST(&cbs); Modified: kos/kernel/thread/thread.c =================================================================== --- kos/kernel/thread/thread.c 2010-12-22 15:27:07 UTC (rev 694) +++ kos/kernel/thread/thread.c 2010-12-27 04:04:30 UTC (rev 695) @@ -1,7 +1,8 @@ /* KallistiOS ##version## - kernel/thread.c - Copyright (c)2000,2001,2002,2003 Dan Potter + kernel/thread/thread.c + Copyright (C) 2000, 2001, 2002, 2003 Dan Potter + Copyright (C) 2010 Lawrence Sebald */ #include <stdlib.h> @@ -12,6 +13,7 @@ #include <reent.h> #include <errno.h> #include <kos/thread.h> +#include <kos/dbgio.h> #include <kos/sem.h> #include <kos/rwsem.h> #include <kos/recursive_lock.h> @@ -31,13 +33,9 @@ Some of this code ought to look familiar to BSD-heads; I studied the BSD kernel quite a bit to get some ideas on priorities, and I am also using their queue library verbatim (sys/queue.h). - + */ -/* Uncomment the following line to enable experimental jiffyless thread - switching support. Doesn't work very well right now. */ -/* #define JIFFYLESS */ - /*****************************************************************************/ /* Thread scheduler data */ @@ -54,86 +52,86 @@ static struct ktqueue run_queue; /* "Jiffy" count: this is basically a counter that gets incremented each - time a timer interrupt happens. XXX: Deprecated. */ + time a timer interrupt happens. */ vuint32 jiffies; -#ifdef JIFFYLESS -/* Next pre-emption wake up time. If we are in pre-emptive threading mode and - there are multiple tasks contending for the CPU, then this var will have - the next system time that we need to wake up for a context switch. */ -uint64 thd_next_switch; -#endif - /* The currently executing thread. This thread should not be on any queues. */ kthread_t *thd_current = NULL; /* Thread mode: cooperative or pre-emptive. */ int thd_mode = THD_MODE_NONE; +/* Reaper semaphore. Counts the number of threads waiting to be reaped. */ +static semaphore_t *thd_reap_sem; + +/* Number of threads active in the system. */ +static uint32 thd_count = 0; + /*****************************************************************************/ /* Debug */ -#include <kos/dbgio.h> static const char *thd_state_to_str(kthread_t * thd) { - switch(thd->state) { - case STATE_ZOMBIE: - return "zombie"; - case STATE_RUNNING: - return "running"; - case STATE_READY: - return "ready"; - case STATE_WAIT: - if (thd->wait_msg) - return thd->wait_msg; - else - return "wait"; - default: - return "unknown"; - } + switch(thd->state) { + case STATE_ZOMBIE: + return "zombie"; + case STATE_RUNNING: + return "running"; + case STATE_READY: + return "ready"; + case STATE_WAIT: + if (thd->wait_msg) + return thd->wait_msg; + else + return "wait"; + case STATE_FINISHED: + return "finished"; + default: + return "unknown"; + } } int thd_pslist(int (*pf)(const char *fmt, ...)) { - kthread_t *cur; + kthread_t *cur; - pf("All threads (may not be deterministic):\n"); - pf("addr\t\ttid\tprio\tflags\twait_timeout\tstate name\n"); - - LIST_FOREACH(cur, &thd_list, t_list) { - pf("%08lx\t", CONTEXT_PC(cur->context)); - pf("%d\t", cur->tid); - if (cur->prio == PRIO_MAX) - pf("MAX\t"); - else - pf("%d\t", cur->prio); - pf("%08lx\t", cur->flags); - pf("%ld\t\t", (uint32)cur->wait_timeout); - pf("%10s", thd_state_to_str(cur)); - pf("%s\n", cur->label); - } - pf("--end of list--\n"); + pf("All threads (may not be deterministic):\n"); + pf("addr\t\ttid\tprio\tflags\twait_timeout\tstate name\n"); - return 0; + LIST_FOREACH(cur, &thd_list, t_list) { + pf("%08lx\t", CONTEXT_PC(cur->context)); + pf("%d\t", cur->tid); + if (cur->prio == PRIO_MAX) + pf("MAX\t"); + else + pf("%d\t", cur->prio); + pf("%08lx\t", cur->flags); + pf("%ld\t\t", (uint32)cur->wait_timeout); + pf("%10s", thd_state_to_str(cur)); + pf("%s\n", cur->label); + } + pf("--end of list--\n"); + + return 0; } int thd_pslist_queue(int (*pf)(const char *fmt, ...)) { - kthread_t *cur; + kthread_t *cur; - pf("Queued threads:\n"); - pf("addr\t\ttid\tprio\tflags\twait_timeout\tstate name\n"); - TAILQ_FOREACH(cur, &run_queue, thdq) { - pf("%08lx\t", CONTEXT_PC(cur->context)); - pf("%d\t", cur->tid); - if (cur->prio == PRIO_MAX) - pf("MAX\t"); - else - pf("%d\t", cur->prio); - pf("%08lx\t", cur->flags); - pf("%ld\t\t", (uint32)cur->wait_timeout); - pf("%10s", thd_state_to_str(cur)); - pf("%s\n", cur->label); - } + pf("Queued threads:\n"); + pf("addr\t\ttid\tprio\tflags\twait_timeout\tstate name\n"); + TAILQ_FOREACH(cur, &run_queue, thdq) { + pf("%08lx\t", CONTEXT_PC(cur->context)); + pf("%d\t", cur->tid); + if (cur->prio == PRIO_MAX) + pf("MAX\t"); + else + pf("%d\t", cur->prio); + pf("%08lx\t", cur->flags); + pf("%ld\t\t", (uint32)cur->wait_timeout); + pf("%10s", thd_state_to_str(cur)); + pf("%s\n", cur->label); + } - return 0; + return 0; } /*****************************************************************************/ @@ -142,25 +140,24 @@ /* Highest thread id (used when assigning next thread id) */ static tid_t tid_highest; - /* Return the next available thread id (assumes wraparound will not run into old processes). */ static tid_t thd_next_free() { - int id; - id = tid_highest++; - return id; + int id; + id = tid_highest++; + return id; } /* Given a thread ID, locates the thread structure */ kthread_t *thd_by_tid(tid_t tid) { - kthread_t *np; + kthread_t *np; - LIST_FOREACH(np, &thd_list, t_list) { - if (np->tid == tid) - return np; - } + LIST_FOREACH(np, &thd_list, t_list) { + if (np->tid == tid) + return np; + } - return NULL; + return NULL; } @@ -169,57 +166,89 @@ /* An idle function. This function literally does nothing but loop forever. It's meant to be used for an idle task. */ -static void thd_idle_task(void *param) { - /* Uncomment these if you want some debug for deadlocking */ +static void *thd_idle_task(void *param) { + /* Uncomment these if you want some debug for deadlocking */ /* int old = irq_disable(); #ifndef NDEBUG - thd_pslist(); - printf("Inside idle task now\n"); + thd_pslist(); + printf("Inside idle task now\n"); #endif - irq_restore(old); */ - for (;;) { - arch_sleep(); /* We can safely enter sleep mode here */ - } + irq_restore(old); */ + for (;;) { + arch_sleep(); /* We can safely enter sleep mode here */ + } + + /* Never reached */ + abort(); } +/* Reaper function. This function is here to reap old zombie threads as they are + created. */ +static void *thd_reaper(void *param) { + kthread_t *thd; + + for(;;) { + /* Wait til we have something to reap */ + sem_wait(thd_reap_sem); + + /* Find the first zombie thread and reap it (only do one at a time so + that the semaphore stays current) */ + LIST_FOREACH(thd, &thd_list, t_list) { + if(thd->state == STATE_ZOMBIE) { + thd_destroy(thd); + break; + } + } + } + + /* Never reached */ + abort(); +} + /* Thread execution wrapper; when the thd_create function below adds a new thread to the thread chain, this function is the one that gets called in the new context. */ -void thd_birth(void (*routine)(void *param), void *param) { - /* Call the thread function */ - routine(param); +static void thd_birth(void *(*routine)(void *param), void *param) { + /* Call the thread function */ + void *rv = routine(param); - /* Die */ - thd_exit(); + /* Die */ + thd_exit(rv); } /* Terminate the current thread */ -void thd_exit() { - kthread_tls_kv_t *i, *i2; +void thd_exit(void *rv) { + /* The thread's never coming back so we don't need to bother saving the + interrupt state at all. Disable interrupts just to make sure nothing + changes underneath us while we're doing our thing here */ + irq_disable(); - /* Clean up any thread-local data. */ - LIST_FOREACH(i, &thd_current->tls_list, kv_list) { - if(i->destructor) { - i->destructor(i->data); - } - } + /* Set the return value of the thread */ + thd_current->rv = rv; - i = LIST_FIRST(&thd_current->tls_list); - while(i != NULL) { - i2 = LIST_NEXT(i, kv_list); - free(i); - i = i2; - } + /* Call newlib's thread cleanup function */ + if(thd_current->thd_reent.__cleanup) { + thd_current->thd_reent.__cleanup(_impure_ptr); + } - /* Call Dr. Kevorkian; after this executes we could be killed - at any time. */ - thd_current->state = STATE_ZOMBIE; + if(thd_current->flags & THD_DETACHED) { + /* Call Dr. Kevorkian; after this executes we could be killed + at any time. */ + thd_current->state = STATE_ZOMBIE; + sem_signal(thd_reap_sem); + } + else { + /* Mark the thread as finished and wake up anyone that has tried to join + with it */ + thd_current->state = STATE_FINISHED; + genwait_wake_all(thd_current); + } - /* Manually reschedule */ - thd_block_now(&thd_current->context); + /* Manually reschedule */ + thd_block_now(&thd_current->context); - /* not reached */ - abort(); + /* not reached */ + abort(); } @@ -231,140 +260,164 @@ right before the process group of the same priority (front_of_line!=0). See thd_schedule for why this is helpful. */ void thd_add_to_runnable(kthread_t *t, int front_of_line) { - kthread_t *i; - int done; + kthread_t *i; + int done; - if (t->flags & THD_QUEUED) - return; + if (t->flags & THD_QUEUED) + return; - done = 0; + done = 0; - if (!front_of_line) { - /* Look for a thread of lower priority and insert - before it. If there is nothing on the run queue, we'll - fall through to the bottom. */ - TAILQ_FOREACH(i, &run_queue, thdq) { - if (i->prio > t->prio) { - TAILQ_INSERT_BEFORE(i, t, thdq); - done = 1; - break; - } - } - } else { - /* Look for a thread of the same or lower priority and - insert before it. If there is nothing on the run queue, - we'll fall through to the bottom. */ - TAILQ_FOREACH(i, &run_queue, thdq) { - if (i->prio >= t->prio) { - TAILQ_INSERT_BEFORE(i, t, thdq); - done = 1; - break; - } - } - } + if (!front_of_line) { + /* Look for a thread of lower priority and insert + before it. If there is nothing on the run queue, we'll + fall through to the bottom. */ + TAILQ_FOREACH(i, &run_queue, thdq) { + if (i->prio > t->prio) { + TAILQ_INSERT_BEFORE(i, t, thdq); + done = 1; + break; + } + } + } else { + /* Look for a thread of the same or lower priority and + insert before it. If there is nothing on the run queue, + we'll fall through to the bottom. */ + TAILQ_FOREACH(i, &run_queue, thdq) { + if (i->prio >= t->prio) { + TAILQ_INSERT_BEFORE(i, t, thdq); + done = 1; + break; + } + } + } - /* Didn't find one, put it at the end */ - if (!done) - TAILQ_INSERT_TAIL(&run_queue, t, thdq); + /* Didn't find one, put it at the end */ + if (!done) + TAILQ_INSERT_TAIL(&run_queue, t, thdq); - t->flags |= THD_QUEUED; + t->flags |= THD_QUEUED; } /* Removes a thread from the runnable queue, if it's there. */ int thd_remove_from_runnable(kthread_t *thd) { - if (!(thd->flags & THD_QUEUED)) return 0; - thd->flags &= ~THD_QUEUED; - TAILQ_REMOVE(&run_queue, thd, thdq); - return 0; + if (!(thd->flags & THD_QUEUED)) return 0; + thd->flags &= ~THD_QUEUED; + TAILQ_REMOVE(&run_queue, thd, thdq); + return 0; } /* New thread function; given a routine address, it will create a new kernel thread with a default stack. When the routine returns, the thread will exit. Returns the new thread struct. */ -kthread_t *thd_create(void (*routine)(void *param), void *param) { - kthread_t *nt; - tid_t tid; - uint32 params[2]; - int oldirq = 0; +kthread_t *thd_create(int detach, void *(*routine)(void *param), void *param) { + kthread_t *nt = NULL; + tid_t tid; + uint32 params[2]; + int oldirq = 0; - nt = NULL; + oldirq = irq_disable(); - oldirq = irq_disable(); + /* Get a new thread id */ + tid = thd_next_free(); + if (tid >= 0) { + /* Create a new thread structure */ + nt = malloc(sizeof(kthread_t)); + if (nt != NULL) { + /* Clear out potentially unused stuff */ + memset(nt, 0, sizeof(kthread_t)); - /* Get a new thread id */ - tid = thd_next_free(); - if (tid >= 0) { - /* Create a new thread structure */ - nt = malloc(sizeof(kthread_t)); - if (nt != NULL) { - /* Clear out potentially unused stuff */ - memset(nt, 0, sizeof(kthread_t)); - - /* Create a new thread stack */ - nt->stack = (uint32*)malloc(THD_STACK_SIZE); - nt->stack_size = THD_STACK_SIZE; - - /* Populate the context */ - params[0] = (uint32)routine; - params[1] = (uint32)param; - irq_create_context(&nt->context, - ((uint32)nt->stack)+nt->stack_size, - (uint32)thd_birth, params, 0); + /* Create a new thread stack */ + nt->stack = (uint32*)malloc(THD_STACK_SIZE); + nt->stack_size = THD_STACK_SIZE; - nt->tid = tid; - nt->prio = PRIO_DEFAULT; - nt->flags = THD_DEFAULTS; - nt->state = STATE_READY; - strcpy(nt->label, "[un-named kernel thread]"); - if (thd_current) - strcpy(nt->pwd, thd_current->pwd); - else - strcpy(nt->pwd, "/"); + /* Populate the context */ + params[0] = (uint32)routine; + params[1] = (uint32)param; + irq_create_context(&nt->context, + ((uint32)nt->stack)+nt->stack_size, + (uint32)thd_birth, params, 0); - _REENT_INIT_PTR((&(nt->thd_reent))); + nt->tid = tid; + nt->prio = PRIO_DEFAULT; + nt->flags = THD_DEFAULTS; + nt->state = STATE_READY; + strcpy(nt->label, "[un-named kernel thread]"); + if (thd_current) + strcpy(nt->pwd, thd_current->pwd); + else + strcpy(nt->pwd, "/"); - /* Initialize thread-local storage. */ - LIST_INIT(&nt->tls_list); + _REENT_INIT_PTR((&(nt->thd_reent))); - /* Insert it into the thread list */ - LIST_INSERT_HEAD(&thd_list, nt, t_list); + /* Should we detach the thread? */ + if(detach) { + nt->flags |= THD_DETACHED; + } - /* Schedule it */ - thd_add_to_runnable(nt, 0); - } - } + /* Initialize thread-local storage. */ + LIST_INIT(&nt->tls_list); - irq_restore(oldirq); - return nt; + /* Insert it into the thread list */ + LIST_INSERT_HEAD(&thd_list, nt, t_list); + + /* Add it to our count */ + ++thd_count; + + /* Schedule it */ + thd_add_to_runnable(nt, 0); + } + } + + irq_restore(oldirq); + return nt; } /* Given a thread id, this function removes the thread from the execution chain. */ int thd_destroy(kthread_t *thd) { - int oldirq = 0; + int oldirq = 0; + kthread_tls_kv_t *i, *i2; - /* Make sure there are no ints */ - oldirq = irq_disable(); + /* Make sure there are no ints */ + oldirq = irq_disable(); - /* If any threads were waiting on this one, then go ahead - and unblock them. */ - genwait_wake_all(thd); + /* If any threads were waiting on this one, then go ahead + and unblock them. */ + genwait_wake_all(thd); - /* De-schedule the thread if it's scheduled and free the - thread structure */ - thd_remove_from_runnable(thd); - LIST_REMOVE(thd, t_list); + /* De-schedule the thread if it's scheduled and free the + thread structure */ + thd_remove_from_runnable(thd); + LIST_REMOVE(thd, t_list); - /* Free its stack */ - free(thd->stack); + /* Clean up any thread-local data */ + LIST_FOREACH(i, &thd->tls_list, kv_list) { + if(i->destructor) { + i->destructor(i->data); + } + } - /* Free the thread */ - free(thd); + i = LIST_FIRST(&thd->tls_list); + while(i != NULL) { + i2 = LIST_NEXT(i, kv_list); + free(i); + i = i2; + } - /* Put ints back the way they were */ - irq_restore(oldirq); + /* Free its stack */ + free(thd->stack); - return 0; + /* Free the thread */ + free(thd); + + /* Remove it from the count */ + --thd_count; + + /* Put ints back the way they were */ + irq_restore(oldirq); + + return 0; } /*****************************************************************************/ @@ -372,9 +425,9 @@ /* Set a thread's priority */ int thd_set_prio(kthread_t *thd, prio_t prio) { - /* Set the new priority */ - thd->prio = prio; - return 0; + /* Set the new priority */ + thd->prio = prio; + return 0; } /*****************************************************************************/ @@ -395,83 +448,68 @@ IRQ after doing something like a sem_signal, where you'd ideally like to make sure the priorities are all straight before returning, but you don't want a full context switch inside the same priority group. - */ +*/ void thd_schedule(int front_of_line, uint64 now) { - int dontenq, count; - kthread_t *thd, *tnext; + int dontenq; + kthread_t *thd; - if (now == 0) - now = timer_ms_gettime64(); + if (now == 0) + now = timer_ms_gettime64(); - /* We won't re-enqueue the current thread if it's NULL (i.e., the - thread blocked itself somewhere) or if it's a zombie (below) */ - dontenq = thd_current == NULL ? 1 : 0; - - /* Destroy all threads marked STATE_ZOMBIE */ - thd = LIST_FIRST(&thd_list); - count = 0; - while (thd != NULL) { - tnext = LIST_NEXT(thd, t_list); + /* We won't re-enqueue the current thread if it's NULL (i.e., the + thread blocked itself somewhere) or if it's a zombie (below) */ + dontenq = !thd_current; - if (thd->state == STATE_ZOMBIE) { - if (thd == thd_current) - dontenq = 1; - thd_destroy(thd); - } + /* If there's only two thread left, it's the idle task and the reaper task: + exit the OS */ + if (thd_count == 2) { + dbgio_printf("\nthd_schedule: idle tasks are the only things left; exiting\n"); + arch_exit(); + } - thd = tnext; - count++; - } + /* Re-queue the last "current" thread onto the run queue if + it didn't die */ + if (!dontenq && thd_current->state == STATE_RUNNING) { + thd_current->state = STATE_READY; + thd_add_to_runnable(thd_current, front_of_line); + } - /* If there's only one thread left, it's the idle task: exit the OS */ - if (count == 1) { - dbgio_printf("\nthd_schedule: idle task is the only thing left; exiting\n"); - arch_exit(); - } + /* Look for timed out waits */ + genwait_check_timeouts(now); - /* Re-queue the last "current" thread onto the run queue if - it didn't die */ - if (!dontenq && thd_current->state == STATE_RUNNING) { - thd_current->state = STATE_READY; - thd_add_to_runnable(thd_current, front_of_line); - } + /* Search downwards through the run queue for a runnable thread; if + we don't find a normal runnable thread, the idle process will + always be there at the bottom. */ + TAILQ_FOREACH(thd, &run_queue, thdq) { + /* Is it runnable? If not, keep going */ + if (thd->state == STATE_READY) + break; + } - /* Look for timed out waits */ - genwait_check_timeouts(now); + /* Didn't find one? Big problem here... */ + if (thd == NULL) { + thd_pslist(printf); + panic("couldn't find a runnable thread"); + } - /* Search downwards through the run queue for a runnable thread; if - we don't find a normal runnable thread, the idle process will - always be there at the bottom. */ - TAILQ_FOREACH(thd, &run_queue, thdq) { - /* Is it runnable? If not, keep going */ - if (thd->state == STATE_READY) - break; - } + /* We should now have a runnable thread, so remove it from the + run queue and switch to it. */ + thd_remove_from_runnable(thd); - /* Didn't find one? Big problem here... */ - if (thd == NULL) { - thd_pslist(printf); - panic("couldn't find a runnable thread"); - } - - /* We should now have a runnable thread, so remove it from the - run queue and switch to it. */ - thd_remove_from_runnable(thd); + thd_current = thd; + _impure_ptr = &thd->thd_reent; + thd->state = STATE_RUNNING; - thd_current = thd; - _impure_ptr = &thd->thd_reent; - thd->state = STATE_RUNNING; + /* Make sure the thread hasn't underrun its stack */ + if (thd_current->stack && thd_current->stack_size) { + if ( CONTEXT_SP(thd_current->context) < (ptr_t)(thd_current->stack) ) { + thd_pslist(printf); + thd_pslist_queue(printf); + assert_msg( 0, "Thread stack underrun" ); + } + } - /* Make sure the thread hasn't underrun its stack */ - if (thd_current->stack && thd_current->stack_size) { - if ( CONTEXT_SP(thd_current->context) < (ptr_t)(thd_current->stack) ) { - thd_pslist(printf); - thd_pslist_queue(printf); - assert_msg( 0, "Thread stack underrun" ); - } - } - - irq_set_context(&thd_current->context); + irq_set_context(&thd_current->context); } /* Temporary priority boosting function: call this from within an interrupt @@ -479,99 +517,41 @@ interrupt return to jump back to the new thread instead of the one that was executing (unless it was already executing). */ void thd_schedule_next(kthread_t *thd) { - /* Make sure we're actually inside an interrupt */ - if (!irq_inside_int()) - return; + /* Make sure we're actually inside an interrupt */ + if (!irq_inside_int()) + return; - /* Can't boost a blocked thread */ - if (thd->state != STATE_READY) - return; + /* Can't boost a blocked thread */ + if (thd->state != STATE_READY) + return; - /* Unfortunately we have to take care of this here */ - if (thd_current->state == STATE_ZOMBIE) { - thd_destroy(thd_current); - } else if (thd_current->state == STATE_RUNNING) { - thd_current->state = STATE_READY; - thd_add_to_runnable(thd_current, 0); - } + /* Unfortunately we have to take care of this here */ + if (thd_current->state == STATE_ZOMBIE) { + sem_signal(thd_reap_sem); + } + else if (thd_current->state == STATE_RUNNING) { + thd_current->state = STATE_READY; + thd_add_to_runnable(thd_current, 0); + } - thd_remove_from_runnable(thd); - thd_current = thd; - _impure_ptr = &thd->thd_reent; - thd_current->state = STATE_RUNNING; - irq_set_context(&thd_current->context); + thd_remove_from_runnable(thd); + thd_current = thd; + _impure_ptr = &thd->thd_reent; + thd_current->state = STATE_RUNNING; + irq_set_context(&thd_current->context); } -#ifdef JIFFYLESS -/* Looks at our queues and determines when we need to wake up next. */ -static void thd_schedule_switch(uint64 now) { - uint64 nexttmr; - kthread_t * nt; - - assert( thd_current != NULL ); - - /* When is the next timer event due? */ - nexttmr = genwait_next_timeout(); - - /* Are we in cooperative threading? If so, we never need a context - switch timeout. */ - if (thd_mode == THD_MODE_COOP) { - /* Just wake up for the timer event */ - if (nexttmr != 0) { - assert( nexttmr != now ); - timer_primary_wakeup(nexttmr - now); - } - } else { - /* We already should have a runnable task in thd_current. Look also - at the run queue. Is there anything at the same priority level - as the current thread? */ - nt = TAILQ_FIRST(&run_queue); - if (nt != NULL && nt->prio <= thd_current->prio) { - /* Is the timeslice time more than the next timer event? If so - then don't bother with a pre-emption timer. */ - if ((nexttmr - now) >= thd_next_switch) { - /* We need a timeslice pre-emption. Make it so! */ - assert( thd_next_switch != now ); - timer_primary_wakeup(thd_next_switch - now); - } else { - /* Just wake up for the timer event. */ - assert( nexttmr != now ); - timer_primary_wakeup(nexttmr - now); - } - } else { - /* Just wake up for the next timer event */ - if (nexttmr != 0) { - assert( nexttmr != now ); - timer_primary_wakeup(nexttmr - now); - } else { - thd_next_switch = 0; - } - } - } -} -#endif /* JIFFYLESS */ - /* See kos/thread.h for description */ irq_context_t * thd_choose_new() { - uint64 now = timer_ms_gettime64(); + uint64 now = timer_ms_gettime64(); - //printf("thd_choose_new() woken at %d\n", (uint32)now); + //printf("thd_choose_new() woken at %d\n", (uint32)now); - /* Do any re-scheduling */ - thd_schedule(0, now); + /* Do any re-scheduling */ + thd_schedule(0, now); -#ifdef JIFFYLESS - /* Increment the context switch counter */ - jiffies++; - - /* Schedule a new next-switch event */ - thd_next_switch = now + 1000/HZ; - //printf(" resetting thd_next_switch to %d\n", (uint32)thd_next_switch); - thd_schedule_switch(now); -#endif - - /* Return the new IRQ context back to the caller */ - return &thd_current->context; + /* Return the new IRQ context back to the caller */ + return &thd_current->context; } /*****************************************************************************/ @@ -581,33 +561,13 @@ again until our next context switch (if any). For pre-empts, re-schedule threads, swap out contexts, and sleep. */ static void thd_timer_hnd(irq_context_t *context) { - /* Get the system time */ - uint64 now = timer_ms_gettime64(); + /* Get the system time */ + uint64 now = timer_ms_gettime64(); - //printf("timer woke at %d\n", (uint32)now); + //printf("timer woke at %d\n", (uint32)now); -#ifdef JIFFYLESS - /* Did we wake up for a timer event or a context switch? */ - if (thd_next_switch && now >= thd_next_switch) { - /* Do any re-scheduling. Note that thd_schedule() also checks - for timeouts, so if we had those simultaneous with a context - switch it'll get caught here. */ - thd_schedule(0, now); - - /* Schedule the next context switch. */ - thd_next_switch = now + 1000/HZ; - //printf("resetting thd_next_switch to %ld\n", (uint32)thd_next_switch); - } else { - /* Just deal with timers */ - genwait_check_timeouts(now); - } - - /* Request a wakeup at the next time we will need to re-schedule. */ - thd_schedule_switch(now); -#else - thd_schedule(0, now); - timer_primary_wakeup(1000/HZ); -#endif + thd_schedule(0, now); + timer_primary_wakeup(1000/HZ); } /*****************************************************************************/ @@ -616,131 +576,176 @@ sleep because it eases the load on the system for the other threads. */ void thd_sleep(int ms) { - if (thd_mode == THD_MODE_NONE) { - timer_spin_sleep(ms); - return; - } + if (thd_mode == THD_MODE_NONE) { + timer_spin_sleep(ms); + return; + } - /* A timeout of zero is the same as thd_pass() and passing zero - down to genwait_wait() causes bad juju. */ - if (!ms) { - thd_pass(); - return; - } + /* A timeout of zero is the same as thd_pass() and passing zero + down to genwait_wait() causes bad juju. */ + if (!ms) { + thd_pass(); + return; + } - /* We can genwait on a non-existant object here with a timeout and - have the exact same effect; as a nice bonus, this collapses both - sleep cases into a single case, which is nice for scheduling - purposes. 0xffffffff definitely doesn't exist as an object, so we'll - use that for straight up timeouts. */ - genwait_wait((void *)0xffffffff, "thd_sleep", ms, NULL); + /* We can genwait on a non-existant object here with a timeout and + have the exact same effect; as a nice bonus, this collapses both + sleep cases into a single case, which is nice for scheduling + purposes. 0xffffffff definitely doesn't exist as an object, so we'll + use that for straight up timeouts. */ + genwait_wait((void *)0xffffffff, "thd_sleep", ms, NULL); } /* Manually cause a re-schedule */ void thd_pass() { - /* Makes no sense inside int */ - if (irq_inside_int()) return; + /* Makes no sense inside int */ + if (irq_inside_int()) return; - /* Pass off control manually */ - thd_block_now(&thd_current->context); + /* Pass off control manually */ + thd_block_now(&thd_current->context); } /* Wait for a thread to exit */ -int thd_wait(kthread_t * thd) { - int old, rv; - kthread_t * t = NULL; +int thd_join(kthread_t * thd, void **value_ptr) { + int old, rv; + kthread_t * t = NULL; - /* Can't scan for NULL threads */ - if (thd == NULL) - return -1; + /* Can't scan for NULL threads */ + if (thd == NULL) + return -1; - if (irq_inside_int()) { - dbglog(DBG_WARNING, "thd_wait(%p) called inside an interrupt!\n", thd); - return -1; - } + if (irq_inside_int()) { + dbglog(DBG_WARNING, "thd_join(%p) called inside an interrupt!\n", thd); + return -1; + } - old = irq_disable(); - - /* Search the thread list and make sure that this thread hasn't - already died and been deallocated. */ - LIST_FOREACH(t, &thd_list, t_list) { - if (t == thd) - break; - } + old = irq_disable(); - /* Did we find anything? */ - if (t != thd) { - rv = -2; - } else { - /* Wait for the target thread to die */ - genwait_wait(thd, "thd_wait", 0, NULL); + /* Search the thread list and make sure that this thread hasn't + already died and been deallocated. */ + LIST_FOREACH(t, &thd_list, t_list) { + if (t == thd) + break; + } - /* Ok, we're all clear */ - rv = 0; - } + /* Did we find anything? */ + if (t != thd) { + rv = -2; + } + else if (thd->flags & THD_DETACHED) { + /* Can't join a detached thread */ + rv = -3; + } + else { + if(thd->state != STATE_FINISHED) { + /* Wait for the target thread to die */ + genwait_wait(thd, "thd_join", 0, NULL); + } - irq_restore(old); - return rv; + /* Ok, we're all clear */ + rv = 0; + + if(value_ptr) + *value_ptr = thd->rv; + + /* The thread can be destroyed now */ + thd_destroy(thd); + } + + irq_restore(old); + return rv; } +/* Detach a joinable thread */ +int thd_detach(kthread_t *thd) { + int old, rv = 0; + kthread_t * t = NULL; + + /* Can't scan for NULL threads */ + if (thd == NULL) + return -1; + + old = irq_disable(); + + /* Search the thread list and make sure that this thread hasn't + already died and been deallocated. */ + LIST_FOREACH(t, &thd_list, t_list) { + if (t == thd) + break; + } + + /* Did we find anything? */ + if (t != thd) { + rv = -2; + } + else if (thd->flags & THD_DETACHED) { + /* Can't detach an already detached thread */ + rv = -3; + } + else if (thd->state == STATE_FINISHED) { + /* If the thread is already finished, deallocate it now */ + thd_destroy(thd); + } + else { + /* Set the detached flag and return */ + thd->flags |= THD_DETACHED; + } + + irq_restore(old); + return rv; +} + + /*****************************************************************************/ /* Retrive / set thread label */ const char *thd_get_label(kthread_t *thd) { - return thd->label; + return thd->label; } void thd_set_label(kthread_t *thd, const char *label) { - strncpy(thd->label, label, sizeof(thd->label) - 1); + strncpy(thd->label, label, sizeof(thd->label) - 1); } /* Find the current thread */ kthread_t *thd_get_current() { - return thd_current; + return thd_current; } /* Retrieve / set thread pwd */ const char *thd_get_pwd(kthread_t *thd) { - return thd->pwd; + return thd->pwd; } void thd_set_pwd(kthread_t *thd, const char *pwd) { - strncpy(thd->pwd, pwd, sizeof(thd->pwd) - 1); + strncpy(thd->pwd, pwd, sizeof(thd->pwd) - 1); } int * thd_get_errno(kthread_t * thd) { - return &thd->thd_errno; + return &thd->thd_errno; } struct _reent * thd_get_reent(kthread_t *thd) { - return &thd->thd_reent; + return &thd->thd_reent; } /*****************************************************************************/ /* Change threading modes */ int thd_set_mode(int mode) { - int old = thd_mode; + int old = thd_mode; - /* Nothing to change? */ - if (thd_mode == mode) - return thd_mode; + /* Nothing to change? */ + if (thd_mode == mode) + return thd_mode; - if (thd_mode == THD_MODE_COOP) { - /* Schedule our first pre-emption wakeup */ -#ifdef JIFFYLESS - thd_next_switch = timer_ms_gettime64() + 1000/HZ; -#endif - timer_primary_wakeup(1000/HZ); - } else { -#ifdef JIFFYLESS - /* Don't do any more pre-empt wakeups */ - thd_next_switch = 0; -#endif - } + if (thd_mode == THD_MODE_COOP) { + /* Schedule our first pre-emption wakeup */ + timer_primary_wakeup(1000/HZ); + } - thd_mode = mode; + thd_mode = mode; - return old; + return old; } /* Delete a TLS key. Note that currently this doesn't prevent you from reusing @@ -789,108 +794,113 @@ /* Init */ int thd_init(int mode) { - kthread_t *idle, *kern; + kthread_t *idle, *kern, *reaper; - /* Make sure we're not already running */ - if (thd_mode != THD_MODE_NONE) - return -1; + /* Make sure we're not already running */ + if (thd_mode != THD_MODE_NONE) + return -1; - /* Setup our mode as appropriate */ - thd_mode = mode; + /* Setup our mode as appropriate */ + thd_mode = mode; - /* Initialize handle counters */ - tid_highest = 1; + /* Initialize handle counters */ + tid_highest = 1; - /* Initialize the thread list */ - LIST_INIT(&thd_list); + /* Initialize the thread list */ + LIST_INIT(&thd_list); - /* Initialize the run queue */ - TAILQ_INIT(&run_queue); + /* Initialize the run queue */ + TAILQ_INIT(&run_queue); - /* Start off with no "current" thread */ - thd_current = NULL; + /* Start off with no "current" thread */ + thd_current = NULL; - /* Init thread-local storage. */ - kthread_tls_init(); + /* Init thread-local storage. */ + kthread_tls_init(); - /* Setup a kernel task for the currently running "main" thread */ - kern = thd_create(NULL, NULL); - strcpy(kern->label, "[kernel]"); - kern->state = STATE_RUNNING; + /* Reinitialize thread counter */ + thd_count = 0; - /* De-scehdule the thread (it's STATE_RUNNING) */ - thd_remove_from_runnable(kern); - - /* Setup an idle task that is always ready to run, in case everyone - else is blocked on something. */ - idle = thd_create(thd_idle_task, NULL); - strcpy(idle->label, "[idle]"); - thd_set_prio(idle, PRIO_MAX); - idle->state = STATE_READY; + /* Setup a kernel task for the currently running "main" thread */ + kern = thd_create(0, NULL, NULL); + strcpy(kern->label, "[kernel]"); + kern->state = STATE_RUNNING; - /* Main thread -- the kern thread */ - thd_current = kern; - irq_set_context(&kern->context); + /* De-scehdule the thread (it's STATE_RUNNING) */ + thd_remove_from_runnable(kern); - /* Re-initialize jiffy counter */ - jiffies = 0; + /* Setup an idle task that is always ready to run, in case everyone + else is blocked on something. */ + idle = thd_create(0, thd_idle_task, NULL); + strcpy(idle->label, "[idle]"); + thd_set_prio(idle, PRIO_MAX); + idle->state = STATE_READY; - /* Initialize thread sync primitives */ - genwait_init(); - rwsem_init(); - rlock_init(); - sem_init(); - cond_init(); + /* Set up a thread to reap old zombies */ + thd_reap_sem = sem_create(0); + reaper = thd_create(0, thd_reaper, NULL); + strcpy(reaper->label, "[reaper]"); + thd_set_prio(reaper, PRIO_MAX - 1); - /* Setup our pre-emption handler */ - timer_primary_set_callback(thd_timer_hnd); + /* Main thread -- the kern thread */ + thd_current = kern; + irq_set_context(&kern->context); - /* If we're in pre-emptive mode, then schedule the first context switch */ - if (thd_mode == THD_MODE_PREEMPT) { - /* Schedule our first wakeup */ -#ifdef JIFFYLESS - thd_next_switch = timer_ms_gettime64() + 1000/HZ; -#endif - timer_primary_wakeup(1000/HZ); + /* Re-initialize jiffy counter */ + jiffies = 0; - printf("thd: pre-emption enabled, HZ=%d\n", HZ); - } else - printf("thd: pre-emption disabled\n"); + /* Initialize thread sync primitives */ + genwait_init(); + rwsem_init(); + rlock_init(); + sem_init(); + cond_init(); - return 0; + /* Setup our pre-emption handler */ + timer_primary_set_callback(thd_timer_hnd); + + /* If we're in pre-emptive mode, then schedule the first context switch */ + if (thd_mode == THD_MODE_PREEMPT) { + /* Schedule our first wakeup */ + timer_primary_wakeup(1000/HZ); + + printf("thd: pre-emption enabled, HZ=%d\n", HZ); + } else + printf("thd: pre-emption disabled\n"); + + return 0; } /* Shutdown */ void thd_shutdown() { - kthread_t *n1, *n2; + kthread_t *n1, *n2; - /* Disable pre-emption, if neccessary */ - if (thd_mode == THD_MODE_PREEMPT) { - timer_primary_set_callback(NULL); - } + /* Disable pre-emption, if neccessary */ + if (thd_mode == THD_MODE_PREEMPT) { + timer_primary_set_callback(NULL); + } - /* Kill remaining live threads */ - n1 = LIST_FIRST(&thd_list); - while (n1 != NULL) { - n2 = LIST_NEXT(n1, t_list); - free(n1->stack); - free(n1); - n1 = n2; - } + /* Kill remaining live threads */ + n1 = LIST_FIRST(&thd_list); + while (n1 != NULL) { + n2 = LIST_NEXT(n1, t_list); + free(n1->stack); + free(n1); + n1 = n2; + } - /* Shutdown thread sync primitives */ - rwsem_shutdown(); - rlock_shutdown(); - sem_shutdown(); - cond_shutdown(); - genwait_shutdown(); + /* Shutdown thread sync primitives */ + rwsem_shutdown(); + rlock_shutdown(); + sem_shutdown(); + cond_shutdown(); + genwait_shutdown(); - kthread_tls_shutdown(); + kthread_tls_shutdown(); - /* Not running */ - thd_mode = THD_MODE_NONE; + /* Not running */ + thd_mode = THD_MODE_NONE; + thd_count = 0; - // XXX _impure_ptr is borked + // XXX _impure_ptr is borked } - - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2010-12-22 15:27:13
|
Revision: 694 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=694&view=rev Author: ljsebald Date: 2010-12-22 15:27:07 +0000 (Wed, 22 Dec 2010) Log Message: ----------- A bit of a lwIP hack so that it will actually compile again. Modified Paths: -------------- kos-ports/lwip/lwip/src/include/ipv4/lwip/inet.h kos-ports/lwip/lwip/src/include/ipv4/lwip/ip_addr.h Modified: kos-ports/lwip/lwip/src/include/ipv4/lwip/inet.h =================================================================== --- kos-ports/lwip/lwip/src/include/ipv4/lwip/inet.h 2010-11-21 05:59:11 UTC (rev 693) +++ kos-ports/lwip/lwip/src/include/ipv4/lwip/inet.h 2010-12-22 15:27:07 UTC (rev 694) @@ -44,9 +44,11 @@ struct ip_addr *src, struct ip_addr *dest, u8_t proto, u32_t proto_len); +#ifndef __ARPA_INET_H u32_t inet_addr(const char *cp); int inet_aton(const char *cp, struct in_addr *addr); u8_t *inet_ntoa(u32_t addr); /* returns ptr to static buffer; not reentrant! */ +#endif #ifdef htons #undef htons Modified: kos-ports/lwip/lwip/src/include/ipv4/lwip/ip_addr.h =================================================================== --- kos-ports/lwip/lwip/src/include/ipv4/lwip/ip_addr.h 2010-11-21 05:59:11 UTC (rev 693) +++ kos-ports/lwip/lwip/src/include/ipv4/lwip/ip_addr.h 2010-12-22 15:27:07 UTC (rev 694) @@ -40,7 +40,10 @@ #define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any) #define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast) +#ifndef INADDR_NONE #define INADDR_NONE ((u32_t) 0xffffffff) /* 255.255.255.255 */ +#endif + #define INADDR_LOOPBACK ((u32_t) 0x7f000001) /* 127.0.0.1 */ /* Definitions of the bits in an Internet address integer. @@ -89,9 +92,11 @@ #endif /* For compatibility with BSD code */ +#ifndef __NETINET_IN_H struct in_addr { u32_t s_addr; }; +#endif extern const struct ip_addr ip_addr_any; extern const struct ip_addr ip_addr_broadcast; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2010-11-21 05:59:18
|
Revision: 693 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=693&view=rev Author: ljsebald Date: 2010-11-21 05:59:11 +0000 (Sun, 21 Nov 2010) Log Message: ----------- - Mark all children of the root directory as directories in a readdir. - Mark all children of /vmu as directories in a readdir. Modified Paths: -------------- kos/kernel/arch/dreamcast/fs/fs_vmu.c kos/kernel/fs/fs.c Modified: kos/kernel/arch/dreamcast/fs/fs_vmu.c =================================================================== --- kos/kernel/arch/dreamcast/fs/fs_vmu.c 2010-10-30 20:50:48 UTC (rev 692) +++ kos/kernel/arch/dreamcast/fs/fs_vmu.c 2010-11-21 05:59:11 UTC (rev 693) @@ -481,14 +481,18 @@ /* Ok, extract it and fill the dirent struct */ dir = dh->dirblocks + dh->entry; - if (dh->rootdir) + if (dh->rootdir) { dh->dirent.size = -1; - else + dh->dirent.attr = O_DIR; + } + else { dh->dirent.size = dir->filesize*512; + dh->dirent.attr = 0; + } + strncpy(dh->dirent.name, dir->filename, 12); dh->dirent.name[12] = 0; dh->dirent.time = 0; /* FIXME */ - dh->dirent.attr = 0; /* Move to the next entry */ dh->entry++; Modified: kos/kernel/fs/fs.c =================================================================== --- kos/kernel/fs/fs.c 2010-10-30 20:50:48 UTC (rev 692) +++ kos/kernel/fs/fs.c 2010-11-21 05:59:11 UTC (rev 693) @@ -85,6 +85,7 @@ if (nmhnd == NULL) return NULL; + root_readdir_dirent.attr = O_DIR; root_readdir_dirent.size = -1; if (nmhnd->pathname[0] == '/') strcpy(root_readdir_dirent.name, nmhnd->pathname+1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |