[BACK]Return to arch.html CVS log [TXT][DIR] Up to [local] / prex-old / doc / html / doc

File: [local] / prex-old / doc / html / doc / arch.html (download) (as text)

Revision 1.1, Tue Jun 3 09:38:42 2008 UTC (15 years, 11 months ago) by nbrk
Branch point for: MAIN

Initial revision

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>Architecture Dependent Interface</title>
  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
  <meta name="keywords" content="Prex, embedded, real-time, operating system, RTOS, open source, free">
  <meta name="author" content="Kohsuke Ohtani">
  <link rel="stylesheet" type="text/css" href="../default.css" media="screen">
  <link rel="stylesheet" type="text/css" href="../print.css" media="print">
</head>
<body>
<div id="top">
</div>
<div id="middle">

<table id="content" cellpadding="0" cellspacing="0">
  <tbody>

    <tr>
      <td id="header" colspan="2" valign="top">
        <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td id="logo">
            <a href="http://prex.sourceforge.net/">
            <img alt="Prex logo" src="../img/logo.gif" border="0"
            style="width: 281px; height: 56px;"></a>
          </td>
          <td id="brief" align="right" valign="bottom">
            An Open Source, Royalty-free,<br>
	    Real-time Operating System
          </td>
        </tr>
        </table>
      </td>
    </tr>

    <tr>
      <td id="directory" style="vertical-align: top;">
      <a href="http://prex.sourceforge.net/">Prex Home</a> >
      <a href="index.html">Document Index</a> >
      Architecture Dependent Interface
    </tr>
    <tr><td class="pad" colspan="2" style="vertical-align: top;"></td></tr>

    <tr>
      <td id="main" style="vertical-align: top;">
      <h1>Prex Architecture Dependent Interface</h1>

<p>
<i>Version 1.0.2, 2007/12/23</i>
</p>

<h3>Table of Contents</h3>
<ul>
  <li><a href="#intro">Introduction</a></li>
</ul>
<ul>
  <li><a href="#gen">General Information</a>
  <ul>
    <li><a href="#gen">Data Types</a></li>
  </ul>
  </li>
</ul>
<ul>
  <li><a href="#context">Context</a>
  <ul>
    <li><a href="#context">context_init</a></li>
    <li><a href="#context">context_set</a></li>
    <li><a href="#context">context_switch</a></li>
    <li><a href="#context">context_save</a></li>
    <li><a href="#context">context_restore</a></li>
  </ul>
  </li>
</ul>
<ul>
  <li><a href="#int">Interrupt</a>
  <ul>
    <li><a href="#int">interrupt_enable</a></li>
    <li><a href="#int">interrupt_disable</a></li>
    <li><a href="#int">interrupt_save</a></li>
    <li><a href="#int">interrupt_restore</a></li>
    <li><a href="#int">interrupt_mask</a></li>
    <li><a href="#int">interrupt_unmask</a></li>
    <li><a href="#int">interrupt_setup</a></li>
  </ul>
  </li>
</ul>
<ul>
  <li><a href="#mmu">MMU</a>
  <ul>
    <li><a href="#mmu">mmu_init</a></li>
    <li><a href="#mmu">mmu_map</a></li>
    <li><a href="#mmu">mmu_newmap</a></li>
    <li><a href="#mmu">mmu_delmap</a></li>
    <li><a href="#mmu">mmu_switch</a></li>
    <li><a href="#mmu">mmu_extract</a></li>
  </ul>
  </li>
</ul>
<ul>
  <li><a href="#clock">Clock</a>
  <ul>
    <li><a href="#clock">clock_init</a></li>
  </ul>
  </li>
</ul>
<ul>
  <li><a href="#umem">User Memory</a>
  <ul>
    <li><a href="#umem">umem_copyin</a></li>
    <li><a href="#umem">umem_copyout</a></li>
    <li><a href="#umem">umem_strnlen</a></li>
  </ul>
  </li>
</ul>
<ul>
  <li><a href="#diag">Diagnostic</a>
  <ul>
    <li><a href="#diag">diag_init</a></li>
    <li><a href="#diag">diag_print</a></li>
  </ul>
  </li>
</ul>
<ul>
  <li><a href="#mach">Machine</a>
  <ul>
    <li><a href="#mach">machine_init</a></li>
    <li><a href="#mach">machine_idle</a></li>
    <li><a href="#mach">machine_reset</a></li>
  </ul>
  </li>
</ul>
<ul>
  <li><a href="#loc">Memory Location</a>
  <ul>
    <li><a href="#loc">kern_area</a></li>
    <li><a href="#loc">user_area</a></li>
    <li><a href="#loc">phys_to_virt</a></li>
    <li><a href="#loc">virt_to_phys</a></li>
  </ul>
  </li>
</ul>
<br>
<br>

<h2 id="intro">Introduction</h2>

<p>
The interface for the architecture dependent layer is defined to abstract
a processor and minimum hardware in the Prex kernel.
If you want to port the Prex kernel to new architecture or new platform,
you have to modify the architecture dependent codes properly for
your target system. 
</p>
<p>
Some functions are optional on the specific target.
For example, you don't have to implement the MMU support code if your
target system does not have a MMU.
</p>
<p>
The interface described here is used only by the kernel code.
And, it is not defined to provide hardware abstraction for device drivers.
So, it is different from the layer generally called as HAL (Hardware Abstraction Layer).
</p>

<h2 id="gen">General Information</h2>

<h3>Data Types</h3>
<p>
The following data types are defined by the architecture dependent layer.

</p>
<table border="1" width="60%" cellspacing="0">
<tbody>
<tr>
  <th>Data type</th>
  <th>Description</th>
</tr>
<tr>
  <td>context_t</td>
  <td>Define a processor register set for the thread context.</td>
</tr>
<tr>
  <td>pgd_t</td>
  <td>Define a page directory for the MMU.</td>
</tr>

</tbody>
</table>

<h2 id="context">Context</h2>
<p>
A context includes processor registers and additional per-thread
information. context_t represents the pointer to the context structure
of each architecture/platform. The kernel treats the pointer as a context
ID and it does not touch the internal data of the context structure.
</p>
<pre>
void context_init(context_t ctx, u_long kstack);
void context_set(context_t ctx, int type, void *val);
void context_switch(context_t prev, context_t next);
void context_save(context_t ctx, int exc);
void context_restore(context_t ctx, void *regs);
</pre>

<dl>
<dt>context_init()</dt>
<dd>
Initializes the context identified by <i>ctx</i>.
It fills some processor registers with known default values. The
kernel stack pointer is set as <i>kstack</i> value.
</dd>
</dl>

<dl>
<dt>context_set()</dt>
<dd>
Sets data <i>val</i> to the specific registers in <i>ctx</i>.
The <i>type</i> is one of the following register type.
<ul>
  <li>CTX_UENTRY - Set the user mode entry address.</li>
  <li>CTX_USTACK - Set the user mode stack address.</li>
  <li>CTX_KENTRY - Set the kernel mode entry address.</li>
  <li>CTX_KARG   - Set the kernel mode argument.</li>
</ul>
</dd>
</dl>

<dl>
<dt>context_switch()</dt>
<dd>
Switches the current context to new
context pointed by <i>next</i>.
</dd>
</dl>

<dl>
<dt>context_save()</dt>
<dd>
Saves the current user mode context to the thread local stack.
This is used to handle an exception, and the exception number is
stored in <i>exc</i>.
</dd>
</dl>

<dl>
<dt>context_restore()</dt>
<dd>
Restores the saved user mode context to the
specified context. The pointer to user mode registers is specified by <i>reg</i>.
</dd>
</dl>


<h2 id="int">Interrupt</h2>
<p>
The kernel abstracts whole interrupt related hardware. 
The architecture dependent interface provides only primitive routines
to handle the interrupt.
</p>

<pre>
void interrupt_enable(void);
void interrupt_disable(void);
void interrupt_save(int *sts);
void interrupt_restore(int sts);
void interrupt_mask(int vector);
void interrupt_unmask(int vector, int level);
void interrupt_setup(int vector, int mode);
</pre>

<dl>
<dt>interrupt_enable()</dt>
<dd>
Enables all interrupts.
</dd>
</dl>

<dl>
<dt>interrupt_disable()</dt>
<dd>
Disables all interrupts.
</dd>
</dl>

<dl>
<dt>interrupt_save()</dt>
<dd>
Saves current interrupt state to the address of <i>sts</i>.
</dd>
</dl>

<dl>
<dt>interrupt_restore()</dt>
<dd>
Restores the saved interrupt state from <i>sts</i>.
</dd>
</dl>

<dl>
<dt>interrupt_mask()</dt>
<dd>
Masks the interrupt for the specified interrupt <i>vector</i>.
</dd>
</dl>

<dl>
<dt>interrupt_unmask()</dt>
<dd>
Unmasks the interrupt for the specified
interrupt <i>vector</i>. The interrupt priority level is set to <i>level</i>.
</dd>
</dl>

<dl>
<dt>interrupt_setup()</dt>
<dd>
Programs the interrupt mode. <i>mode</i> is one of
the following value.
    <ul>
      <li>IMODE_EDGE - Edge trigger</li>
      <li>IMODE_LEVEL - Level trigger</li>
    </ul>
</dd>
</dl>

<h2 id="mmu">MMU</h2>
<p>
The architecture dependent code must provide the functions for
Memory Management Unit (MMU). Even if the system does not support MMU,
mmu_init() and mmu_switch() must be defined as NULL macro.
</p>

<pre>
void  mmu_init(void);
int   mmu_map(pgd_t pgd, void *phys, void *virt, size_t size, int type);
pgd_t mmu_newmap(void);
void  mmu_delmap(pgd_t pgd);
void  mmu_switch(pgd_t pgd);
void *mmu_extract(pgd_t pgd, void *virt, size_t size);
</pre>

<dl>
<dt>mmu_init()</dt>
<dd>
Initializes the memory management unit.
</dd>
</dl>

<dl>
<dt>mmu_map()</dt>
<dd>
Maps physical memory range <i>phys</i> into the
virtual address <i>virt</i>. <i>type</i> is one of the following mapping type.
<ul>
  <li>PG_UNMAP - Remove mapping</li>
  <li>PG_READ - Read only mapping</li>
  <li>PG_WRITE - Read/write are allowed</li>
</ul>
It returns 0 on success, or -1 on failure.
</dd>
</dl>

<dl>
<dt>mmu_newmap()</dt>
<dd>
Creates a new map. It returns new page directory on success,
or NULL on failure. This routine will be called when new task is created.
</dd>
</dl>

<dl>
<dt>mmu_delmap()</dt>
<dd>
Deletes all page mapping in the page directory <i>pgd</i>.
</dd>
</dl>

<dl>
<dt>mmu_switch()</dt>
<dd>
Switchs to new page directory specified in <i>pgd</i>. This is called when
the thread is switched.
</dd>
</dl>

<dl>
<dt>mmu_extract()</dt>
<dd>
Returns the physical address for the specified virtual
address. It returns NULL if at least one page is not mapped.
</dd>
</dl>

<h2 id="clock">Clock</h2>
The Prex kernel requires a clock timer hardware for all systems.
<pre>
void clock_init(void);
</pre>

<dl>
<dt>clock_init()</dt>
<dd>
Initializes the clock timer device.
</dd>
</dl>

<h2 id="umem">User Memory</h2>
<p>
Since accessing to the user memory may cause a page fault, 
the manipulation of the user buffer is handled by each architecture codes.
The following functions should detect the page fault and return an error
if it can.
</p>

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

<dl>
<dt>umem_copyin</dt>
<dd>
Copies the data to the kernel area from the user buffer.
It returns 0 on success, or EFAULT on page fault.
</dd>
</dl>

<dl>
<dt>umem_copyout</dt>
<dd>
Copies the data from the kernel buffer to the user area.
It returns 0 on success, or EFAULT on page fault.
</dd>
</dl>

<dl>
<dt>umem_strnlen</dt>
<dd>
Gets the string length specified in <i>uaddr</i>.
It returns 0 on success, or EFAULT on page fault.
</dd>
</dl>


<h2 id="diag">Diagnostic</h2>

<pre>
void diag_init(void);
void diag_print(char *buf);
</pre>

<dl>
<dt>diag_init()</dt>
<dd>
Initialize diagnostic port.
</dd>
</dl>

<dl>
<dt>diag_print()</dt>
<dd>
Puts the message specified by <i>buf</i> to the output device.
</dd>
</dl>


<h2 id="mach">Machine</h2>

<pre>
void machine_init(void);
void machine_idle(void);
void machine_reset(void);
</pre>

<dl>
<dt>machine_init()</dt>
<dd>
Initialize basic h/w.
</dd>
</dl>

<dl>
<dt>machine_idle()</dt>
<dd>
Sets the system to the low power mode until any interrupt occurs.
</dd>
</dl>

<dl>
<dt>machine_reset()</dt>
<dd>
Resets the system.
</dd>
</dl>


<h2 id="loc">Memory Location</h2>
<pre>
int   kern_area(void *addr);
int   user_area(void *addr);
void *phys_to_virt(void *p_addr);
void *virt_to_phys(void *v_addr);
</pre>

<dl>
<dt>kern_area()</dt>
<dd>
Returns true if specified <i>addr</i> is in the kernel area.
</dd>
</dl>

<dl>
<dt>user_area()</dt>
<dd>
Returns true if specified <i>addr</i> is in the user area.
</dd>
</dl>

<dl>
<dt>phys_to_virt()</dt>
<dd>
Returns the virtual address mapped to the
physical address in <i>p_addr</i>.
</dd>
</dl>

<dl>
<dt>virt_to_phys()</dt>
<dd>
Returns the physical address mapped to the
virtual address in <i>v_addr</i>.
</dd>
</dl>

      </td>
    </tr>
    <tr>
      <td id="footer" colspan="2" style="vertical-align: top;">
        <a href="http://sourceforge.net">
        <img src="http://sourceforge.net/sflogo.php?group_id=132028&amp;type=1"
        alt="SourceForge.net Logo" border="0" height="31" width="88"></a><br>
        Copyright&copy; 2005-2007 Kohsuke Ohtani
      </td>
    </tr>

  </tbody>
</table>

</div>
<div id="bottom"></div>

</body>
</html>