comp.lang.ada
 help / color / mirror / Atom feed
From: anon@anon.org (anon)
Subject: Re: How do I go about creating a minimal GNAT runtime?
Date: Mon, 26 Jan 2009 21:36:33 GMT
Date: 2009-01-26T21:36:33+00:00	[thread overview]
Message-ID: <B1qfl.154905$_Y1.69794@bgtnsc05-news.ops.worldnet.att.net> (raw)
In-Reply-To: eb511600-6446-4bad-b859-0d7444416a4c@d36g2000prf.googlegroups.com


For Kernels and GNAT there are three classes of exceptions.  The first two 
classes are not directly handled by GNAT Ada and must be programmed to 
be handled.

The first class of exceptions are device exceptions. Such as when a device 
stop working or is not present.  In this case, during initialization, the 
kernel could just display a message to the video or uses the speaker to 
alert the user, that there is a problem, then the kernel halts the CPU.  
After initialization normally, the device drivers could generate a 
software exception if an error occurs, that can handled by an Ada 
exception routine.

The second class of exceptions are caused by the hardware.  In this level 
there are two exceptions types: CPU, and Hardware.  The CPU type 
exceptions are predefined and are generated by the CPU, such as memory 
"Page-Faults" or an integer "Divide-by-Zero" exceptions.  Now, the 
Hardware exceptions are generated by the hardware and causes the CPU to 
generate an interrupt similar to the CPU exception.  To handle this class of 
exceptions the x86 kernel will first need to set up the "Interrupt 
Description Table" register and then use a wrapper to call the correct Ada 
interrupt handler routine. 

The x86 kernels uses the protective "LIDT" assembly statement to setup the 
Interrupt Description Table Register. This register contains a pointer to an 
jump array or table where the array is defined large enough to handle all 
CPU and Hardware interrupts (exceptions) with maybe a few extra entries 
for software interrupts.  And each entry of this array is a pointer to a 
wrapper. Which in turns call an Ada routine that processes the interrupt 
or exception. The general IDT and wrapper design is:

  IDT register => wrapper_table

  wrapper_table := ( 0 => wrapper_0'address,
                     2 => wrapper_1'address,
                     3 => wrapper_2'address,
                     ... ) ;

: Assembly code:
      wrapper_0:
               save   : all general and segment registers
               call Ada interrupt handler for exception 0
               restore: all general and segment registers
               "IRET" -- special interrupt return statement 
      wrapper_1:
               save   : all general and segment registers
               call Ada interrupt handler for exception 1
               restore: all general and segment registers
               "IRET" -- special interrupt return statement 
      ...

The reason the wrapper is used is that GNAT does not generated the 
special interrupt return statement "IRET" which is needed for all 
interrupt routines.

An example of a Hardware exception is the keyboard interrupt handler.  In 
this case, when a key is press the keyboard controller causes an CPU 
interrupt.  Then the keyboard interrupt routine would read the keystroke 
from the controller and if space is available the keystone will be stored in 
a keyboard queue. Then the routine returns and waits until the next key is 
pressed. Of course, there is another keyboard device driver routine that 
reads the keyboard queue, and passed the value to Ada.Text_IO 'GET' or 
'GET_IMMEDIATE' routines.


The third exception level is the use of Ada.Exception. In this case you may 
need to rewrite the complete package.  And due to the way GNAT was 
designed you will need to make sure that 'Run-Time Check Routines' are 
present. These routines are exceptions that are inserted by the compiler.

A 'Run-Time Check Routines' example is when the compiler encounters a 
divide statement such as:
    Z := X / Y ;

the compiler expands the statement logically to:

    if Y = 0 then
      raise CONSTRAINT_ERROR ( "divide by zero" & File & Line_Number ) ;
    end if ;
    Z := X / Y ;

and is translated to:
    if Y = 0 then
      Rcheck_03 ( File, Line_Number ) ; -- Rcheck_03 is no return procedure.
    end if ;
    Z := X / Y ;

then translated into the assembly statements.

Note: GNAT does not normally allow the use of the CPU exceptions such as 
"divide-by-zero", it checks and trap the exception before the divide 
statement is executed.


In <eb511600-6446-4bad-b859-0d7444416a4c@d36g2000prf.googlegroups.com>, Lucretia <lucretia9@lycos.co.uk> writes:
>Hi (again),
>
>It's been a while, but I'm coming back to my Ada kernel again. I've
>been messing with my helo_world_kernel which I built using no runtime
>(see http://www.archeia.com for more info).
>
>Having just spoken to Ludovic on #Ada, he pointed out that the gnat
>tools can use a basic cross tool set, like the ones I have built
>myself (again, see the above link). My toolset comprises of a gnat1
>compiler and a gnatbind for my targets. I found that it does work
>using the --GCC and --GNATBIND flags, and I need to make sure the
>cross tools and the host tools are of the same GCC version otherwise
>GNAT throws up ALI format errors.
>
>The thing is, I've been trying to enable exceptions, but keep coming
>across big problems in that the runtime requires features that are
>being restricted, such as returning aggregates and assigning
>composites, returning unconstrained objects which requires the
>secondary stack. So, what I really need to know is, how do I create a
>runtime which is restricted in this way for bare hw access?
>
>Thanks,
>Luke.




  parent reply	other threads:[~2009-01-26 21:36 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-24 20:47 How do I go about creating a minimal GNAT runtime? Lucretia
2009-01-25 11:13 ` Ludovic Brenta
2009-01-25 11:18   ` Ludovic Brenta
2009-01-25 14:00     ` Lucretia
2009-01-25 14:00   ` Lucretia
2009-01-25 19:43     ` Ludovic Brenta
2009-01-25 20:30 ` xavier grave
2009-01-26  6:52 ` anon
2009-01-26 21:36 ` anon [this message]
2009-02-10  2:34 ` Exceptions (was Re: How do I go about creating a minimal GNAT runtime?) anon
2009-02-16  1:41 ` How do I go about creating a minimal GNAT runtime? Hibou57 (Yannick Duchêne)
2009-02-21  9:11 ` Dimonax
2009-02-21 16:41   ` anon
2009-02-21 21:14     ` Dimonax
2009-02-22  1:36       ` anon
2009-02-27 23:42   ` Randy Brukardt
2009-03-01  1:12     ` Dimonax
2009-03-01 19:13       ` anon
2009-03-02 22:07         ` Randy Brukardt
2009-03-03  2:00           ` anon
2009-03-03 22:23             ` lucretia
2009-03-04  0:03               ` anon
2009-03-11 12:54   ` gautier_niouzes
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox