mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
7.6 KiB
220 lines
7.6 KiB
|
|
|
|
|
|
// scheduling algorithm for split periodic
|
|
|
|
#ifndef __SCHED_H__
|
|
#define __SCHED_H__
|
|
|
|
#define MAXCEPS 30
|
|
|
|
// all times are in units of bytes
|
|
#define FS_BYTES_PER_MICROFRAME 188
|
|
#define MICROFRAMES_PER_FRAME 8
|
|
#define FS_SOF 6 // number of byte times allocated to an SOF packet at the beginning of a frame
|
|
//#define MAXFRAMES 8 // scheduling window for budget tracking, periods longer than
|
|
#define MAXFRAMES 32 // scheduling window for budget tracking, periods longer than
|
|
// this are reduced to this. Also impacts space required for
|
|
// tracking data structures. Otherwise fairly arbitrary.
|
|
|
|
#define MAXMICROFRAMES (MAXFRAMES * 8)
|
|
|
|
// 4 byte sync, 4 byte split token, 1 byte EOP, 11 byte ipg, plus
|
|
// 4 byte sync, 3 byte regular token, 1 byte EOP, 11 byte ipg
|
|
#define HS_SPLIT_SAME_OVERHEAD 39
|
|
// 4 byte sync, 4 byte split token, 1 byte EOP, 11 byte ipg, plus
|
|
// 4 byte sync, 3 byte regular token, 1 byte EOP, 1 byte bus turn
|
|
#define HS_SPLIT_TURN_OVERHEAD 29
|
|
// 4 byte sync, 1 byte PID, 2 bytes CRC16, 1 byte EOP, 11 byte ipg
|
|
#define HS_DATA_SAME_OVERHEAD 19
|
|
// 4 byte sync, 1 byte PID, 2 bytes CRC16, 1 byte EOP, 1 byte bus turn
|
|
#define HS_DATA_TURN_OVERHEAD 9
|
|
// 4 byte sync, 1 byte PID, 1 byte EOP, 1 byte bus turn
|
|
#define HS_HANDSHAKE_OVERHEAD 7
|
|
//#define HS_MAX_PERIODIC_ALLOCATION 6000 // floor(0.8*7500)
|
|
#define HS_MAX_PERIODIC_ALLOCATION 7000 // floor(0.8*7500)
|
|
|
|
// This could actually be a variable based on an HC implementation
|
|
// some measurements have shown 3?us between transactions or about 3% of a microframe
|
|
// which is about 200+ byte times. We'll use about half that for budgeting purposes.
|
|
#define HS_HC_THINK_TIME 100
|
|
|
|
// 4 byte sync, 3 byte regular token, 1 byte EOP, 11 byte ipg
|
|
#define HS_TOKEN_SAME_OVERHEAD 19
|
|
// 4 byte sync, 3 byte regular token, 1 byte EOP, 1 byte bus turn
|
|
#define HS_TOKEN_TURN_OVERHEAD 9
|
|
|
|
// TOKEN: 1 byte sync, 3 byte token, 3 bit EOP, 1 byte ipg
|
|
// DATA: 1 byte sync, 1 byte PID, 2 bytes CRC16, 3 bit EOP, 1 byte ipg
|
|
// HANDSHAKE: 1 byte sync, 1 byte PID, 3 bit EOP, 1 byte ipg
|
|
#define FS_ISOCH_OVERHEAD 9
|
|
#define FS_INT_OVERHEAD 13
|
|
//#define LS_INT_OVERHEAD (19*8)
|
|
#define LS_INT_OVERHEAD ((14 *8) + 5)
|
|
#define HUB_FS_ADJ 30 // periodic allocation at beginning of frame for use by hubs, maximum allowable is 60 bytes
|
|
#define FS_MAX_PERIODIC_ALLOCATION (1157) // floor(0.9*1500/1.16)
|
|
#define FS_BS_MAX_PERIODIC_ALLOCATION 1350 // floor(0.9*1500), includes bitstuffing allowance (for HC classic allocation)
|
|
|
|
// byte time to qualify as a large FS isoch transaction
|
|
// 673 = 1023/1.16 (i.e. 881) - 1microframe (188) - adj (30) or
|
|
// 1/2 of max allocation in this case
|
|
// #define LARGEXACT (881-FS_BYTES_PER_MICROFRAME)
|
|
#define LARGEXACT (579)
|
|
|
|
typedef struct _Endpoint *PEndpoint;
|
|
|
|
typedef struct _frame_rec
|
|
{
|
|
unsigned time_used:16; // The number of bytes that are budgeted for all endpoints in this frame
|
|
PEndpoint allocated_large; // endpoint if xact over LARGEXACT bytes is allocated in this frame
|
|
PEndpoint isoch_ehead; // many frames can point to the same endpoint. endpoints are linked
|
|
PEndpoint int_ehead; // in longest to shortest period.
|
|
//
|
|
// NOTE: always start with a "dummy" endpoint for SOF on the lists to avoid empty list corner condition
|
|
//
|
|
} frame_rec;
|
|
|
|
typedef struct _HC *PHC;
|
|
typedef struct _TT *PTT;
|
|
|
|
typedef enum {bulk, control, interrupt, isoch} eptype;
|
|
|
|
#define HSSPEED 2
|
|
#define FSSPEED 1
|
|
#define LSSPEED 0
|
|
#define INDIR 0
|
|
#define OUTDIR 1
|
|
typedef struct _Endpoint
|
|
{
|
|
unsigned type;
|
|
|
|
// These fields have static information that is valid/constant as long as an
|
|
// endpoint is configured
|
|
unsigned max_packet:16; // maximum number of data bytes allowed for this
|
|
// endpoint. 0-8 for LS_int, 0-64 for FS_int,
|
|
// 0-1023 for FS_isoch.
|
|
unsigned period:16; // desired period of transactions, assumed to be a power of 2
|
|
eptype ep_type:4;
|
|
unsigned direction:1;
|
|
unsigned speed:2;
|
|
unsigned moved_this_req:1; // 1 when this endpoint has been changed during this allocation request
|
|
PTT mytt; // the TT that roots this classic device.
|
|
|
|
// These fields hold dynamically calculated information that changes as (other)
|
|
// endpoints are added/removed.
|
|
|
|
unsigned calc_bus_time:16; // bytes of FS/LS bus time this endpoint requires
|
|
// including overhead. This can be calculated once.
|
|
|
|
unsigned start_time:16; // classic bus time at which this endpoint is budgeted to occupy the classic bus
|
|
|
|
unsigned actual_period:16; // requested period can be modified:
|
|
// 1. when period is greater than scheduling window (MAXFRAMES)
|
|
// 2. if period is reduced (not currently done by algorithm)
|
|
|
|
unsigned start_frame:8; // first bus frame that is allocated to this endpoint.
|
|
int start_microframe:8; // first bus microframe (in a frame) that can have a
|
|
// start-split for this ep.
|
|
// Complete-splits always start 2 microframes after a
|
|
// start-split.
|
|
unsigned num_starts:4; // the number of start splits.
|
|
unsigned num_completes:4; // the number of complete splits.
|
|
/* The numbers above could be (better?) represented as bitmasks. */
|
|
|
|
/* corner conditions above: coder beware!!
|
|
patterns can have the last CS in the "next" frame
|
|
This is indicated in this design when:
|
|
(start_microframe + num_completes + 1) > 7
|
|
patterns can have the first SS in the previous frame
|
|
This is indicated in this design when:
|
|
start_microframe = -1
|
|
*/
|
|
|
|
PEndpoint next_ep; // pointer to next (faster/equal period) endpoint in budget
|
|
|
|
int id:16; // not needed for real budgeter
|
|
unsigned saved_period:16; // used during period promotion to hold original period
|
|
unsigned promoted_this_time:1;
|
|
|
|
} Endpoint;
|
|
|
|
typedef struct _TT
|
|
{
|
|
unsigned HS_split_data_time[MAXFRAMES][MICROFRAMES_PER_FRAME]; // HS data bytes used for split completes
|
|
// the above time tracks the data time for all devices rooted in this TT.
|
|
// when the time is below 188 in a microframe, that time is allocated in the
|
|
// HS microframe (in the HS HC budget). When the time is greater than 188
|
|
// only 188 byte times (bit stuffed) is allocated on the HS microframe budget.
|
|
|
|
unsigned num_starts[MAXFRAMES][MICROFRAMES_PER_FRAME];
|
|
|
|
frame_rec frame_budget[MAXFRAMES];
|
|
|
|
PHC myHC;
|
|
|
|
unsigned think_time; // TT reports it inter transaction "think" time. Keep it here.
|
|
unsigned allocation_limit; // maximum allocation allowed for this TT's classic bus
|
|
|
|
struct _Endpoint isoch_head[MAXFRAMES];
|
|
struct _Endpoint int_head[MAXFRAMES];
|
|
} TT;
|
|
|
|
typedef struct _microframe_rec
|
|
{
|
|
unsigned time_used;
|
|
|
|
} microframe_rec;
|
|
|
|
typedef struct _HC
|
|
{
|
|
microframe_rec HS_microframe_info[MAXFRAMES][MICROFRAMES_PER_FRAME]; // HS bus time allocated to
|
|
//this host controller
|
|
PTT tthead; // head of list of TTs attached to this HC
|
|
unsigned thinktime;
|
|
unsigned allocation_limit; // maximum allocation allowed for this HC
|
|
int speed; // HS or FS
|
|
|
|
} HC;
|
|
|
|
#if 0
|
|
typedef struct _command {
|
|
char cmd_code;
|
|
int endpoint_number;
|
|
} Cmd_t;
|
|
#endif
|
|
|
|
|
|
/* protoypes */
|
|
void init_hc(PHC myHC);
|
|
|
|
Set_endpoint(
|
|
PEndpoint ep,
|
|
eptype t,
|
|
unsigned d,
|
|
unsigned s,
|
|
unsigned p,
|
|
unsigned m,
|
|
TT *thistt
|
|
);
|
|
|
|
int Allocate_time_for_endpoint(
|
|
PEndpoint ep,
|
|
PEndpoint changed_ep_list[],
|
|
|
|
int *max_changed_eps
|
|
|
|
);
|
|
|
|
void
|
|
init_tt(PHC myHC, PTT myTT);
|
|
|
|
void
|
|
Deallocate_time_for_endpoint(
|
|
PEndpoint ep, // endpoint that needs to be removed (bus time deallocated)
|
|
PEndpoint changed_ep_list[], // pointer to array to set (on return) with list of
|
|
// changed endpoints
|
|
int *max_changed_eps // input: maximum size of (returned) list
|
|
// on return: number of changed endpoints
|
|
);
|
|
|
|
#endif // __SCHED_H__
|