<Other protected methods of off_TmrSrv. >+= (<-U) [<-D->]
// These are for freeze:
// Freeze dynamic resource state at curbuf in buf with avail bytes.
virtual err_t freeze_state(char *buf, char *&curbuf, size_t &avail,
char *&curto, size_t &toavail,
const off_prtl_id_t &frozen_domain) {
return ENOSYS;
}
// Copy static resource state in curbuf with toavail bytes.
virtual err_t copy_state(char *&curto, size_t &toavail) const {
return ENOSYS;
}
<Other protected methods of off_TmrSrv. >+= (<-U) [<-D]
// These are for melt:
// Does resource cleanup. No external resource should be used after
// return.
virtual err_t cleanup(void) { return ENOSYS; }
// Restores the static state from a user supplied buffer.
virtual err_t restore_state(char *&buf, size_t &bsize) { return ENOSYS; }
// Restores dynamic resource state.
virtual err_t melt_state(char *&buf, size_t &bsize, char *&from, size_t &size,
const off_prtl_id_t &melted_domain) {
return ENOSYS;
}
\subsubsection{Freezing timers}
<Other protected methods of off_Tmr. >+= (<-U) [<-D->]
// These are for freeze:
// Freeze dynamic resource state at curbuf in buf with avail bytes.
virtual err_t freeze_state(char *buf, char *&curbuf, size_t &avail,
char *&curto, size_t &toavail,
const off_prtl_id_t &frozen_domain) {
return ENOSYS;
}
// Copy static resource state in curbuf with toavail bytes.
virtual err_t copy_state(char *&curto, size_t &toavail) const {
return ENOSYS;
}
<Other protected methods of off_Tmr. >+= (<-U) [<-D]
// These are for melt:
// Does resource cleanup. No external resource should be used after
// return.
virtual err_t cleanup(void) { return ENOSYS; }
// Restores the static state from a user supplied buffer.
virtual err_t restore_state(char *&buf, size_t &bsize) { return ENOSYS; }
// Restores dynamic resource state.
virtual err_t melt_state(char *&buf, size_t &bsize, char *&from, size_t &size,
const off_prtl_id_t &melted_domain) {
return ENOSYS;
}
To dump a Timer server we use this operator.
<Other public methods of off_TmrSrv. >+= (<-U) [<-D]
// Dumps tmrsrv state.
friend OStr &operator<<(OStr &s, off_TmrSrv &t);
<off_TmrSrv::operator<< implementation. >= (U->)
// Dumps tmrsrv state.
OStr &operator<<(OStr &s, off_TmrSrv &t)
{
s << *(off_HWCompResource*)&t;
s << "name=" << t.nameof() << " url=" << t.get_url() << nl;
return s;
}
<Off timer server implementation dependencies. >+= (U->) [<-D] #include <klib/str.h> // for OStr et al.
\subsection{Timer \cpp{} source files}
Timer server code is kept in hw/TmrSrv.h and hw/TmrSrv.C.
<TmrSrv.h*>= <Read the literate code instead warning. > #ifndef __OFF_TMR_SRV_H #define __OFF_TMR_SRV_H 1 <Off timer server dependencies. > #ifdef __KERNEL__ <Off timer server. > #endif // __KERNEL__ #ifdef __KERNEL__ // Timer server inline methods // <off_TmrSrv::get_allocatorimplementation. > <off_TmrSrv::is_localimplementation. > <off_TmrSrv::operator+implementation. > #endif // __KERNEL__ #endif // __OFF_TMR_SRV_H
<TmrSrv.C*>= <Read the literate code instead warning. > #include <hw/TmrSrv.h> // Exported interface. <Off timer server implementation dependencies. > <Off timer server static members. > <off_TmrSrv::off_TmrSrvimplementation. > <off_TmrSrv::startimplementation. > <off_TmrSrv::allocandfreeimplementation. > <off_TmrSrv::get_urlimplementation. > <off_TmrSrv::nameofimplementation. > <off_TmrSrv::expiredimplementation. > <off_TmrSrv::activateimplementation. > <off_TmrSrv::clock_handlerimplementation. > <off_TmrSrv::alloc_pclkimplementation. > <off_TmrSrv::operator<<implementation. > <off_clock_handlerimplementation. >
Timers are kept in hw/Tmr.h and hw/Tmr.C.
<Tmr.h*>= <Read the literate code instead warning. > #ifndef __OFF_TMR_H #define __OFF_TMR_H 1 <Off timer dependencies. > <Off timer flags. > #ifdef __KERNEL__ <Off timer. > #endif // __KERNEL__ #ifdef __KERNEL__ // Timer inline methods // <off_Tmr::is_periodicimplementation. > <off_Tmr::get_irqlineimplementation. > <off_Tmr::get_ticksimplementation. > <off_Tmr::get_rticksimplementation. > #endif // __KERNEL__ #endif // __OFF_TMR_H
<Tmr.C*>= <Read the literate code instead warning. > #include <hw/Tmr.h> // Exported interface. <Off timer implementation dependencies. > <Off timer static members. > <off_Tmr::off_Tmrimplementation. > <off_Tmr::operator newimplementation. > <off_Tmr::operator deleteimplementation. > <off_Tmr::get_url_holderimplementation. > <off_Tmr::activateimplementation. >
The timer allocator can be found in hw/TmrAllocator.h and
hw/TmrAllocator.C.
<TmrAllocator.h*>=
<Read the literate code instead warning. >
#ifndef __OFF_TMR_ALLOCATOR_H
#define __OFF_TMR_ALLOCATOR_H 1
<Off timer allocator dependencies. >
#ifdef __KERNEL__
<Off linkable timer. >
<Off timer allocator. >
#endif // __KERNEL__
#ifdef __KERNEL__
// Timer allocator inline methods
//
<off_TmrAllocator::operator + implementation. >
#endif // __KERNEL__
#endif // __OFF_TMR_ALLOCATOR_H
<TmrAllocator.C*>=
<Read the literate code instead warning. >
#include <hw/TmrAllocator.h> // Exported interface.
<Off timer allocator static members. >
<off_TmrAllocator::off_TmrAllocator implementation. >
\subsection{Timers for ix86 based architectures}
On Intels, the machine dependent part of the timer server is responsible to handle the programmable interval timer (PIT) chipset. Thus, it allocates PIT IO ports and the actual clock interrupt.
<Off machine dependent timer server. >= (U->)
// An ix86 timer server
//
class off_mdepTmrSrv {
public:
static natural_t get_ntmrs(void) { return OFF_MDEP_NVINT_MAX; }
<Other public methods of off_mdepTmrSrv. >
};
Definesoff_mdepTmrSrv(links are to index).
<Off machine dependent timer server dependencies. >= (U->) #include <flux/types.h> // for boolean_t natural_t et al. #include <klib/limits.h>
PIT is initialized when the machine dependent server is started.
<Other public methods of off_mdepTmrSrv. >= (<-U)
// Starts the PIT
// Interrupts must be cleared!
static void start(natural_t hz);
<off_mdepTmrSrv::start implementation. >= (U->)
// Starts the PIT
void off_mdepTmrSrv::start(natural_t hz)
{
// XXX use APIC instead for SMP.
{
off_io_id_t io(nd.get_iobank(0).get_id(),PITCTL_PORT);
new(&nd.get_iobank(0),io)
off_IOPort(nd.get_proc(0).get_tmr().get_protection(),
nd.get_proc(0).get_tmr().get_domain());
}
{
off_io_id_t io(nd.get_iobank(0).get_id(),PITCTR0_PORT);
new(&nd.get_iobank(0),io)
off_IOPort(nd.get_proc(0).get_tmr().get_protection(),
nd.get_proc(0).get_tmr().get_domain());
}
init_pit(hz);
}
To fully support SMP systems, this implementation has to be changed to program the local APIC instead and a timer server per processor must be created.
<Off machine dependent timer server implementation dependencies.>= (U->) #include <hw/IOBank.h> #include <hw/IOPort.h> #include <node/Node.h> #include <hw/Processor.h> // for clri seti et al. #include <flux/machine/pc/pic.h> // for PIC settings #include <flux/machine/pc/pit.h> // for PIT settings
\subsubsection{Machine dependent timer \cpp{} source files}
Machine dependent timers are kept in mdep/mTmrSrv.h and
mdep/mTmrSrv.C.
<mdep mTmrSrv.h*>= <Read the literate code instead warning. > #ifndef __OFF_MDEP_TMR_SRV_H #define __OFF_MDEP_TMR_SRV_H 1 <Off machine dependent timer server dependencies. > #ifdef __KERNEL__ <Off machine dependent timer server. > #endif // __KERNEL__ #endif // __OFF_MDEP_TMR_SRV_H
<mdep mTmrSrv.C*>=
<Read the literate code instead warning. >
#include <hw/mdep/mTmrSrv.h> // Exported interface
<Off machine dependent timer server implementation dependencies.>
<off_mdepTmrSrv::start implementation. >
t_events for timer t to expire in ticks >: U1, D2
ev. >: U1, D2, D3
ev. >: U1, D2
off_CompResource::make_available. >: U1
off_TmrSrv. >: U1, D2, D3, D4, D5
off_Tmr. >: U1, D2
t_alloc. >: U1, D2
ev to be handled. >: U1, D2
off_clock_handler implementation. >: D1, U2
off_Magic::nameof case for m_numbers. >: D1, D2
off_mdepTmrSrv::start implementation. >: D1, U2
off_Tmr::activate implementation. >: D1, U2
off_TmrAllocator::off_TmrAllocator implementation. >: D1, U2
off_TmrAllocator::operator + implementation. >: D1, U2
off_Tmr::get_irqline implementation. >: D1, U2
off_Tmr::get_rticks implementation. >: D1, U2
off_Tmr::get_ticks implementation. >: D1, U2
off_Tmr::get_url_holder implementation. >: D1, U2
off_Tmr::is_periodic implementation. >: D1, U2
off_Tmr::off_Tmr implementation. >: D1, D2, U3
off_Tmr::operator delete implementation. >: D1, U2
off_Tmr::operator new implementation. >: D1, U2
off_TmrSrv::activate implementation. >: D1, U2
off_TmrSrv::alloc and free implementation. >: D1, U2
off_TmrSrv::alloc_pclk implementation. >: D1, U2
off_TmrSrv::clock_handler implementation. >: D1, U2
off_TmrSrv::expired implementation. >: D1, U2
off_TmrSrv::expired local variables. >: U1, D2
off_TmrSrv::get_allocator implementation. >: D1, U2
off_TmrSrv::get_url implementation. >: D1, U2
off_TmrSrv::is_local implementation. >: D1, U2
off_TmrSrv::nameof implementation. >: D1, U2
off_TmrSrv::off_TmrSrv implementation. >: D1, U2
off_TmrSrv::operator+ implementation. >: D1, U2
off_TmrSrv::operator<< implementation. >: D1, U2
off_TmrSrv::start implementation. >: D1, U2
off_Tmr. >: U1, D2
off_TmrAllocator. >: U1, D2, D3
off_TmrSrv. >: U1, D2, D3, D4, D5, D6, D7, D8, D9
off_Tmr. >: U1, D2
off_Tmr. >: U1, D2, D3, D4, D5
off_TmrSrv. >: U1, D2, D3, D4
off_LTmr. >: U1, D2, D3
off_mdepTmrSrv. >: U1, D2
off_Tmr. >: U1, D2, D3, D4, D5, D6, D7, D8
off_TmrAllocator. >: U1, D2
off_TmrSrv. >: U1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16
ev and reset t_remaining. >: U1, D2
t to expire in ticks at head of t_events. >: U1, D2
periodic flag. >: D1, U2
off_TmrSrv according to mdep. >: U1, D2, D3
t_hz. >: U1, D2
%% --------------------------------------------------------------
DMA objects are used to allocate DMALines. Note that DMA lines
are kept in the kernel although they could have been considered to be
a device (and kept in userland). The reason is efficiency, because we
do not want protection domain crossings just to program a DMA line.
Also, we believe that no flexibility is lost by placing this small
piece of code into the kernel.
<Off DMA table. >=
// Allocation of DMA lines
class off_DMA: public off_HWCompResource {
public:
// Allocates n DMA lines.
off_DMALine *alloc(off_Protection *prot,natural_t n=1,
off_dma_id_t at=OFF_EU_ID_NULL );
// Deallocates the n contiguous DMA lines starting at d.
void free( off_DMALine *d, natural_t n=1 );
//Gets a DMA line from its number.
off_DMALine *operator [](natural_t n) const;
// Starts operation in this memory bank.
err_t start(const off_mdepDMA &dmainfo);
};
Definesoff_DMA(links are to index).
NOTE: XXX must provide off_DMA::off_DMA(void).
\Note{XXX implement off_mdepDMA see off_mdepNode::get_dmainfo
implementation in node.nw for methods used.
DMA lines are very not well modeled, instead we provided a model of DMA pretty close to that of Intel based machines. Future Off portings to different architectures should provide feedback on how should DMA lines be modeled.
<Off DMA line. >=
typedef off_mode_t dma_mode_t;
class off_DMAline: public off_HWResUnit {
public:
// Enables/disables this dma line.
void enable(void);
void disable(void);
// Programs a DMA operation.
void program(off_pg_id_t addr, vm_offset_t length, dma_mode_t mode);
// Gets # of copied or pending bytes.
vm_offset_t get_copied(void);
vm_offset_t get_pending(void);
};
Definesoff_DMALine(links are to index).
<Off DMA line mode data type. >= typedef natural_t dma_mode_t;
Definesdma_mode_t(links are to index).
\subsection{DMA lines for plain users}
DMA related wrappers are straightforward.
<Off DMA table for users. >=
ENTRY class off_uDMA : public off_uHWCompResource {
public:
off_uDMALine *alloc(off_Protection *prot,
natural_t n=1, off_dma_id_t at=OFF_EU_ID_NULL);
void free(off_uDMALine *pf, const off_Rights &r, natural_t n=1 );
off_uDMALine *fetch(off_dma_id_t d,const off_Rights &r) const;
};
Definesoff_uDMA(links are to index).
<Off DMA line for users. >=
ENTRY class off_uDMALine : public off_uHWResUnit {
public:
// Enables/disables this dma line.
void enable(const off_Rights &r);
void disable(const off_Rights &r);
// Programs a DMA operation.
void program(off_pg_id_t addr, vm_offset_t length, dma_mode_t mode,
const off_Rights &r);
// Gets # of copied or pending bytes.
vm_offset_t get_copied(void,const off_Rights &r);
vm_offset_t get_pending(void,const off_Rights &r);
};
Definesoff_uDMALine(links are to index).
%% --------------------------------------------------------------
Next: 4.3 Processors
Up: 4.2.2 Timer server navigation
Previous: 4.2.2.1 Timer server navigation
Francisco J. Ballesteros
1998-05-25