summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-05-27 19:34:37 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-05-27 19:34:37 +0000
commit4050a7fb50ab19ac410e3535d6afe4a65d737fc5 (patch)
treeb8d06633ea163bd7f4df06c6aa6df36ec04f6b5e /c/src/lib/libbsp
parentAdded names for C++ compilers. (diff)
downloadrtems-4050a7fb50ab19ac410e3535d6afe4a65d737fc5.tar.bz2
Numerous changes including the following:
+ DEBUG_EARLY_START re-added (Eric Valette) + segment register initialization (Aleksey/Quality Quorum) + heap size use correction + more debug printk's + increased heap size. Now works with grub boot on all systems I have access to including desktops and a laptop. This is with the i386-rtems tools. Neither i386-rtemself nor netboot produces a working executable.
Diffstat (limited to 'c/src/lib/libbsp')
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start.s253
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c28
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/ldsegs.s170
3 files changed, 194 insertions, 257 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/start/start.s b/c/src/lib/libbsp/i386/pc386/start/start.s
index 3ed542c255..8be3defef4 100644
--- a/c/src/lib/libbsp/i386/pc386/start/start.s
+++ b/c/src/lib/libbsp/i386/pc386/start/start.s
@@ -12,10 +12,8 @@
|
| Instituto Superior Tecnico * Lisboa * PORTUGAL
+--------------------------------------------------------------------------+
-|
| Modified the 20/05/1998 by valette@crf.canon.fr in order to give a working
| example of eraly stage debugging via the DEBUG_EARLY_START define.
-|
+--------------------------------------------------------------------------+
| Disclaimer:
|
@@ -38,22 +36,19 @@
| $Id$
+--------------------------------------------------------------------------*/
+/*
+ * The most trivial start.s possible. It does not know anything
+ * about system it is running on, so it will jump to appropriate
+ * place in BSP specific place to do things it knows nothing about
+ */
#include "asm.h"
/*----------------------------------------------------------------------------+
-| A Descriptor table register has the following format:
-+----------------------------------------------------------------------------*/
-
-.set DTR_LIMIT, 0 # offset of two byte limit
-.set DTR_BASE, 2 # offset of four byte base address
-.set DTR_SIZE, 6 # size of DTR register
-
-/*----------------------------------------------------------------------------+
| Size of heap and stack:
+----------------------------------------------------------------------------*/
-.set HEAP_SIZE, 0x2000
+.set HEAP_SIZE, 256
.set STACK_SIZE, 0x1000
/*----------------------------------------------------------------------------+
@@ -65,20 +60,19 @@ BEGIN_CODE
PUBLIC (start) # GNU default entry point
EXTERN (boot_card)
- EXTERN (load_segments)
- EXTERN (exit)
+ EXTERN (_load_segments)
+ EXTERN (_return_to_monitor)
EXTERN (_IBMPC_initVideo)
- EXTERN (debugPoolingGetChar)
+ EXTERN (debugPollingGetChar)
/*
- * In case it crash on your machine and this is not due
+ * In case this crashes on your machine and this is not due
* to video mode set by the loader, you may try to define
- * the follwoing variable
-#define DEBUG_EARLY_START
+ * the following variable:
*/
-
-SYM (start):
+#define DEBUG_EARLY_START
+SYM (start):
nop
cli # DISABLE INTERRUPTS!!!
#ifdef DEBUG_EARLY_START
@@ -98,12 +92,13 @@ SYM (start):
call printk
addl $4, esp
- call debugPoolingGetChar
+ /*call debugPollingGetChar */
#endif
/*----------------------------------------------------------------------------+
| Load the segment registers (this is done by the board's BSP) and perform any
-| other board specific initialization procedures.
+| other board specific initialization procedures, this piece of code
+| does not know anything about
|
| NOTE: Upon return, gs will contain the segment descriptor for a segment which
| maps directly to all of physical memory.
@@ -119,8 +114,7 @@ SYM (start):
SYM (_establish_stack):
movl $_end, eax # eax = end of bss/start of heap
- addl $HEAP_SIZE, eax # eax = end of heap
- movl eax, stack_start # Save for brk() routine
+ addl _heap_size, eax # eax = end of heap
addl $STACK_SIZE, eax # make room for stack
andl $0xffffffc0, eax # align it on 16 byte boundary
movl eax, esp # set stack pointer
@@ -141,112 +135,18 @@ SYM (zero_bss):
repne # while ecx != 0
stosl # clear a long in the bss
- /*---------------------------------------------------------------------+
- | Copy the Global Descriptor Table to our space
- +---------------------------------------------------------------------*/
-
- sgdt SYM (_Original_GDTR) # save original GDT
- movzwl SYM (_Original_GDTR)+DTR_LIMIT, ecx # size of GDT in bytes;
- # limit is 8192 entries * 8 bytes per
-
- /*---------------------------------------------------------------------+
- | make ds:esi point to the original GDT
- +---------------------------------------------------------------------*/
-
- movl SYM (_Original_GDTR)+DTR_BASE, esi
- push ds # save ds
- movw gs, ax
- movw ax, ds
-
- /*---------------------------------------------------------------------+
- | make es:edi point to the new (our copy) GDT
- +---------------------------------------------------------------------*/
-
- movl $ SYM (_Global_descriptor_table), edi
-
- rep
- movsb # copy the GDT (ds:esi -> es:edi)
-
- pop ds # restore ds
-
- /*---------------------------------------------------------------------+
- | Build and load new contents of GDTR
- +---------------------------------------------------------------------*/
-
- movw SYM (_Original_GDTR)+DTR_LIMIT, ecx # set new limit
- movw cx, SYM (_New_GDTR)+DTR_LIMIT
-
- push $ SYM (_Global_descriptor_table)
- push es
- call SYM (i386_Logical_to_physical)
- addl $6, esp
- movl eax, SYM (_New_GDTR)+DTR_BASE # set new base
-
- cmpb $0, SYM (_Do_Load_GDT) # Should the new GDT be loaded?
- je SYM (no_gdt_load) # NO, then branch
- lgdt SYM (_New_GDTR) # load the new GDT
-
-SYM (no_gdt_load):
-
- /*---------------------------------------------------------------------+
- | Copy the Interrupt Descriptor Table to our space
- +---------------------------------------------------------------------*/
-
- sidt SYM (_Original_IDTR) # save original IDT
- movzwl SYM (_Original_IDTR)+DTR_LIMIT, ecx # size of IDT in bytes;
- #limit is 256 entries * 8 bytes per
-
- /*---------------------------------------------------------------------+
- | make ds:esi point to the original IDT
- +---------------------------------------------------------------------*/
-
- movl SYM (_Original_IDTR)+DTR_BASE, esi
-
- push ds # save ds
- movw gs, ax
- movw ax, ds
-
- /*---------------------------------------------------------------------+
- | make es:edi point to the new (our copy) IDT
- +---------------------------------------------------------------------*/
-
- movl $ SYM (Interrupt_descriptor_table), edi
-
- rep
- movsb # copy the IDT (ds:esi -> es:edi)
- pop ds # restore ds
-
- /*---------------------------------------------------------------------+
- | Build and load new contents of IDTR
- +---------------------------------------------------------------------*/
-
- movw SYM (_Original_IDTR+DTR_LIMIT), ecx # set new limit
- movw cx, SYM (_New_IDTR)+DTR_LIMIT
-
- push $ SYM (Interrupt_descriptor_table)
- push es
- call SYM (i386_Logical_to_physical)
- addl $6, esp
- movl eax, SYM (_New_IDTR)+DTR_BASE # set new base
-
- cmpb $0, SYM (_Do_Load_IDT) # Should the new IDT be loaded?
- je SYM (no_idt_load) # NO, then branch
- lidt SYM (_New_IDTR) # load the new IDT
-
-SYM (no_idt_load):
-
- /*---------------------------------------------------------------------+
- | Initialize the i387.
- |
- | Using the NO WAIT form of the instruction insures that if it is not
- | present the board will not lock up or get an exception.
- +---------------------------------------------------------------------*/
+/*---------------------------------------------------------------------+
+| Initialize the i387.
+|
+| Using the NO WAIT form of the instruction insures that if it is not
+| present the board will not lock up or get an exception.
++---------------------------------------------------------------------*/
fninit # MUST USE NO-WAIT FORM
- /*---------------------------------------------------------------------+
- | Transfer control to User's Board Support Package
- +---------------------------------------------------------------------*/
+/*---------------------------------------------------------------------+
+| Transfer control to User's Board Support Package
++---------------------------------------------------------------------*/
pushl $0 # environp
pushl $0 # argv
@@ -254,106 +154,45 @@ SYM (no_idt_load):
call SYM (boot_card)
addl $12, esp
- /*---------------------------------------------------------------------+
- | Clean up
- +---------------------------------------------------------------------*/
-
- EXTERN (return_to_monitor)
-
- PUBLIC (Bsp_cleanup)
-
-SYM (Bsp_cleanup):
-
- cmpb $0, SYM (_Do_Load_IDT) # Was the new IDT loaded?
- je SYM (no_idt_restore) # NO, then branch
- lidt SYM (_Original_IDTR) # restore the new IDT
-
-SYM (no_idt_restore):
-
- cmpb $0, SYM (_Do_Load_GDT) # Was the new GDT loaded?
- je SYM (no_gdt_restore) # NO, then branch
- lgdt SYM (_Original_GDTR) # restore the new GDT
-
-SYM (no_gdt_restore):
+/*---------------------------------------------------------------------+
+| Clean up - we do not know anything about it, so we will
+| jump to BSP specific code to do cleanup
++---------------------------------------------------------------------*/
jmp SYM (_return_to_monitor)
END_CODE
-/*----------------------------------------------------------------------------+
-| DATA section
-+----------------------------------------------------------------------------*/
-
BEGIN_DATA
- EXTERN (Do_Load_IDT) # defined in the BSP
- EXTERN (Do_Load_GDT) # defined in the BSP
-
- .align 2
- PUBLIC (start_frame)
-SYM (start_frame):
- .long 0
+ PUBLIC(_heap_size)
+SYM(_heap_size):
+ .long HEAP_SIZE << 10
- PUBLIC (stack_start)
-SYM (stack_start):
- .long 0
+ PUBLIC(_stack_size)
+SYM(_stack_size):
+ .long STACK_SIZE
#ifdef DEBUG_EARLY_START
-
+
PUBLIC (welcome_msg)
SYM (welcome_msg) :
.string "Ready to debug RTEMS ?\nEnter <CR>\n"
-#endif
-
-END_DATA
-
-/*----------------------------------------------------------------------------+
-| BSS section
-+----------------------------------------------------------------------------*/
-
-BEGIN_BSS
-
- PUBLIC (_heap_size)
-SYM (_heap_size):
- .long HEAP_SIZE
-
- PUBLIC (_stack_size)
-SYM (_stack_size):
- .long STACK_SIZE
-
- PUBLIC (Interrupt_descriptor_table)
-SYM (Interrupt_descriptor_table):
- .space (256 * 8) # reserve space for all 256 interrupts
+ PUBLIC (hex_msg)
+SYM (hex_msg) :
+ .string "0x%x\n"
- PUBLIC (_Original_IDTR)
-SYM (_Original_IDTR):
- .space DTR_SIZE
+ PUBLIC (made_it_msg)
+SYM (made_it_msg) :
+ .string "made it to %d\n"
- PUBLIC (_New_IDTR)
-SYM (_New_IDTR):
- .space DTR_SIZE
+#endif
- PUBLIC (_Global_descriptor_table)
-SYM (_Global_descriptor_table):
- .space (3 * 8) # the PC386 bsp only needs 3 segment descriptors:
- # NULL, CODE and DATA
- PUBLIC (_Original_GDTR)
-SYM (_Original_GDTR):
- .space DTR_SIZE
+END_DATA
- PUBLIC (_New_GDTR)
-SYM (_New_GDTR):
- .space DTR_SIZE
+END
- PUBLIC (_Physical_base_of_ds)
-SYM (_Physical_base_of_ds):
- .space 4
- PUBLIC (_Physical_base_of_cs)
-SYM (_Physical_base_of_cs):
- .space 4
-END_BSS
-END
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
index 370b7487d7..d952457485 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -81,8 +81,8 @@ void bsp_pretasking_hook(void)
if (rtemsFreeMemStart & (CPU_ALIGNMENT - 1)) /* not aligned => align it */
rtemsFreeMemStart = (rtemsFreeMemStart+CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
- bsp_libc_init((void *)rtemsFreeMemStart, HEAP_SIZE << 10, 0);
- rtemsFreeMemStart += HEAP_SIZE << 10; /* HEAP_SIZE is in KBytes */
+ bsp_libc_init((void *)rtemsFreeMemStart, _heap_size, 0);
+ rtemsFreeMemStart += _heap_size; /* HEAP_SIZE in KBytes */
#ifdef RTEMS_DEBUG
@@ -125,4 +125,28 @@ void bsp_start( void )
BSP_Configuration.work_space_start = (void *)rtemsFreeMemStart;
rtemsFreeMemStart += BSP_Configuration.work_space_size;
+
+ /*
+ * The following information is very useful when debugging.
+ */
+
+#if 0
+ printk( "work_space_size = 0x%x\n", BSP_Configuration.work_space_size );
+ printk( "maximum_extensions = 0x%x\n", BSP_Configuration.maximum_extensions );
+ printk( "microseconds_per_tick = 0x%x\n",
+ BSP_Configuration.microseconds_per_tick );
+ printk( "ticks_per_timeslice = 0x%x\n",
+ BSP_Configuration.ticks_per_timeslice );
+ printk( "maximum_devices = 0x%x\n", BSP_Configuration.maximum_devices );
+ printk( "number_of_device_drivers = 0x%x\n",
+ BSP_Configuration.number_of_device_drivers );
+ printk( "Device_driver_table = 0x%x\n",
+ BSP_Configuration.Device_driver_table );
+
+ printk( "_heap_size = 0x%x\n", _heap_size );
+ printk( "_stack_size = 0x%x\n", _stack_size );
+ printk( "rtemsFreeMemStart = 0x%x\n", rtemsFreeMemStart );
+ printk( "work_space_start = 0x%x\n", BSP_Configuration.work_space_start );
+ printk( "work_space_size = 0x%x\n", BSP_Configuration.work_space_size );
+#endif
} /* bsp_start */
diff --git a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
index 16f791830a..0f120974c6 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
+++ b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s
@@ -43,31 +43,16 @@
#include "asm.h"
/*----------------------------------------------------------------------------+
-| Constants
-+----------------------------------------------------------------------------*/
-.set PROT_DATA_SEG, 0x10 # offset in gdt
-.set RESET_SS, PROT_DATA_SEG # initial value of stack segment register
-.set RESET_DS, PROT_DATA_SEG # initial value of data segment register
-.set RESET_ES, PROT_DATA_SEG # initial value of extra segment register
-.set RESET_FS, PROT_DATA_SEG # initial value of "f" segment register
-.set RESET_GS, PROT_DATA_SEG # initial value of "g" segment register
-
-
-/*----------------------------------------------------------------------------+
-| Macros
-+----------------------------------------------------------------------------*/
-#define LOAD_SEGMENTS(_value, _segment) \
- movw $ ## _value, ax; \
- movw ax, _segment
-
-/*----------------------------------------------------------------------------+
| CODE section
+----------------------------------------------------------------------------*/
BEGIN_CODE
- EXTERN (establish_stack)
+ EXTERN (_establish_stack)
+ EXTERN (Timer_exit)
+ EXTERN (Clock_exit)
+ .p2align 4
/*----------------------------------------------------------------------------+
| delay
+------------------------------------------------------------------------------
@@ -79,30 +64,65 @@ SYM(delay):
/*-------------------------------------------------------------------------+
| Function: _load_segments
-| Description: Load board segment registers with apropriate values +
-| reprogram PIC.
+| Description: Current environment is standard PC booted by grub.
+| So, there is no value in saving current GDT and IDT
+| Settings we have to set it up ourseves. (Naturally
+| it will be not so in case we are booted by some
+| boot monitor, however, then it will be different
+| BSP), After that we have to load board segment registers
+| with apropriate values + reprogram PIC.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
+ .p2align 4
+
PUBLIC (_load_segments)
SYM (_load_segments):
+
+ lgdt SYM(gdtdesc)
+ lidt SYM(idtdesc)
+
+ /* Load CS, flush prefetched queue */
+ ljmp $0x8, $next_step
+
+next_step:
+ /* Load segment registers */
+ movw $0x10, ax
+ movw ax, ss
+ movw ax, ds
+ movw ax, es
+ movw ax, fs
+ movw ax, gs
+
+ /* Set default interrupt handler */
+ movl $0, ecx
+ movl $Interrupt_descriptor_table, eax
+ movl $_default_int_handler, ebx
+ movl ebx, edx
+ sarl $16, edx
+loop:
+ movw bx, (eax)
+ movw $0x8, 2(eax)
+ movw $0x8e00, 4(eax)
+ movw dx, 8(eax)
+ addl $8, eax
+ addl $1, ecx
+ cmpl $255, ecx
+ jle loop
+
- LOAD_SEGMENTS(RESET_SS, ss)
- LOAD_SEGMENTS(RESET_DS, ds)
- LOAD_SEGMENTS(RESET_ES, es)
- LOAD_SEGMENTS(RESET_FS, fs)
- LOAD_SEGMENTS(RESET_GS, gs)
-
- /*---------------------------------------------------------------------+
- | Now we have to reprogram the interrupts :-(. We put them right after
- | the intel-reserved hardware interrupts, at int 0x20-0x2F. There they
- | won't mess up anything. Sadly IBM really messed this up with the
- | original PC, and they haven't been able to rectify it afterwards. Thus
- | the bios puts interrupts at 0x08-0x0f, which is used for the internal
- | hardware interrupts as well. We just have to reprogram the 8259's, and
- | it isn't fun.
- +---------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------+
+| Now we have to reprogram the interrupts :-(. We put them right after
+| the intel-reserved hardware interrupts, at int 0x20-0x2F. There they
+| won't mess up anything. Sadly IBM really messed this up with the
+| original PC, and they haven't been able to rectify it afterwards. Thus
+| the bios puts interrupts at 0x08-0x0f, which is used for the internal
+| hardware interrupts as well. We just have to reprogram the 8259's, and
+| it isn't fun.
++---------------------------------------------------------------------*/
movb $0x11, al /* initialization sequence */
outb al, $0x20 /* send it to 8259A-1 */
@@ -146,6 +166,9 @@ SYM (_load_segments):
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
+
+ .p2align 4
+
PUBLIC (_return_to_monitor)
SYM (_return_to_monitor):
@@ -153,22 +176,73 @@ SYM (_return_to_monitor):
call SYM (Clock_exit)
jmp SYM (start)
-END_CODE
+/*-------------------------------------------------------------------------+
+| Function: _default_int_handler
+| Description: default interrupt handler
+| Global Variables: None.
+| Arguments: None.
+| Returns: Nothing.
++--------------------------------------------------------------------------*/
+ .p2align 4
+
+ PUBLIC (_default_int_handler)
+SYM (_default_int_handler):
+ iret
-/*----------------------------------------------------------------------------+
-| DATA section
-+----------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------+
+| GDT itself
++--------------------------------------------------------------------------*/
+
+ .p2align 4
+
+ PUBLIC (_Global_descriptor_table)
+SYM (_Global_descriptor_table):
-BEGIN_DATA
+ /* NULL segment */
+ .word 0, 0
+ .byte 0, 0, 0, 0
- PUBLIC (_Do_Load_IDT)
-SYM (_Do_Load_IDT):
- .byte 1 # load RTEMS own Interrupt Descriptor Table
+ /* code segment */
+ .word 0xffff, 0
+ .byte 0, 0x9e, 0xcf, 0
- PUBLIC (_Do_Load_GDT)
-SYM (_Do_Load_GDT):
- .byte 0 # use the Global Descriptor Table that is already defined
+ /* data segment */
+ .word 0xffff, 0
+ .byte 0, 0x92, 0xcf, 0
+
+
+/*---------------------------------------------------------------------------+
+| Descriptor of GDT
++--------------------------------------------------------------------------*/
+SYM (gdtdesc):
+ .word (3*8 - 1)
+ .long SYM (_Global_descriptor_table)
-END_DATA
+
+/*---------------------------------------------------------------------------+
+| IDT itself
++---------------------------------------------------------------------------*/
+ .p2align 4
+
+ PUBLIC(Interrupt_descriptor_table)
+SYM(Interrupt_descriptor_table):
+ .rept 256
+ .word 0,0,0,0
+ .endr
+
+/*---------------------------------------------------------------------------+
+| Descriptor of IDT
++--------------------------------------------------------------------------*/
+SYM(idtdesc):
+ .word (256*8 - 1)
+ .long SYM (Interrupt_descriptor_table)
+
+END_CODE
END
+
+
+
+
+
+