1
0
Fork 0
forked from nuttx/nuttx-update

Integrate PIC support into context switching

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1900 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-06-17 23:38:05 +00:00
parent 2afd39df07
commit f876eb552a
13 changed files with 139 additions and 33 deletions

View file

@ -103,6 +103,12 @@
#define REG_LR REG_R14
#define REG_PC REG_R15
/* The PIC register is usually R10. It can be R9 is stack checking is enabled
* or if the user changes it with -mpic-register on the GCC command line.
*/
#define REG_PIC REG_R10
/****************************************************************************
* Public Types
****************************************************************************/

View file

@ -109,6 +109,12 @@
#define REG_LR REG_R14
#define REG_PC REG_R15
/* The PIC register is usually R10. It can be R9 is stack checking is enabled
* or if the user changes it with -mpic-register on the GCC command line.
*/
#define REG_PIC REG_R10
/****************************************************************************
* Public Types
****************************************************************************/

View file

@ -93,6 +93,21 @@ void up_initial_state(_TCB *tcb)
xcp->regs[REG_PC] = (uint32)tcb->start;
/* If this task is running PIC, then set the PIC base register to the
* address of the allocated D-Space region.
*/
#ifdef CONFIG_PIC
if (tcb->dspace != NULL)
{
/* Set the PIC base register (probably R10) to the address of the
* alloacated D-Space region.
*/
xcp->regs[REG_PIC] = (uint32)tcb->dspace->region;
}
#endif
/* Enable or disable interrupts, based on user configuration */
# ifdef CONFIG_SUPPRESS_INTERRUPTS

View file

@ -97,6 +97,21 @@ void up_initial_state(_TCB *tcb)
xcp->regs[REG_XPSR] = CORTEXM3_XPSR_T;
/* If this task is running PIC, then set the PIC base register to the
* address of the allocated D-Space region.
*/
#ifdef CONFIG_PIC
if (tcb->dspace != NULL)
{
/* Set the PIC base register (probably R10) to the address of the
* alloacated D-Space region.
*/
xcp->regs[REG_PIC] = (uint32)tcb->dspace->region;
}
#endif
/* Enable or disable interrupts, based on user configuration */
# ifdef CONFIG_SUPPRESS_INTERRUPTS

View file

@ -145,7 +145,7 @@ int exec_module(FAR const struct binary_s *bin, int priority)
/* Add the DSpace address as the PIC base address */
#ifdef CONFIG_PIC
tcb->picbase = bin->dspace;
tcb->dspace = bin->dspace;
/* Re-initialize the task's initial state to account for the new PIC base */

View file

@ -118,7 +118,7 @@ static void nxflat_reloc(struct nxflat_loadinfo_s *loadinfo, uint32 rl)
* DSpace to hold information needed by ld.so at run time.
*/
datastart = loadinfo->dspace;
datastart = (uint32)loadinfo->dspace->region;
/* Get a pointer to the value that needs relocation in
* DSpace.
@ -257,22 +257,22 @@ int nxflat_load(struct nxflat_loadinfo_s *loadinfo)
* uninitialized ISpace memory.
*/
loadinfo->dspace = (uint32)malloc(loadinfo->dsize);
loadinfo->dspace = (struct dspace_s *)malloc(SIZEOF_DSPACE_S(loadinfo->dsize));
if (loadinfo->dspace == 0)
{
bdbg("Failed to allocate DSpace\n");
ret = -ENOMEM;
goto errout;
}
loadinfo->dspace->crefs = 1;
bvdbg("Allocated DSpace (%d bytes) at %08x\n",
loadinfo->dsize, loadinfo->dspace);
bvdbg("Allocated DSpace (%d bytes) at %p\n", loadinfo->dsize, loadinfo->dspace);
/* Now, read the data into allocated DSpace at doffset into the
* allocated DSpace memory.
*/
ret = nxflat_read(loadinfo, (char*)loadinfo->dspace, dreadsize, doffset);
ret = nxflat_read(loadinfo, (char*)loadinfo->dspace->region, dreadsize, doffset);
if (ret < 0)
{
bdbg("Failed to read .data section: %d\n", ret);
@ -285,10 +285,10 @@ int nxflat_load(struct nxflat_loadinfo_s *loadinfo)
/* Resolve the address of the relocation table. In the file, the
* relocations should lie at the same offset as BSS. The current
* value of relocstart is the offset from the beginning of the file.
* The following adjustment will convert it to an address in DSpace.
* The following adjustment will convert it to an address in dspace->
*/
reloctab = (uint32*)(loadinfo->relocstart + loadinfo->dspace - loadinfo->isize);
reloctab = (uint32*)(loadinfo->relocstart + (uint32)loadinfo->dspace->region - loadinfo->isize);
bvdbg("Relocation table at 0x%p, reloccount=%d\n",
reloctab, loadinfo->reloccount);
@ -304,7 +304,7 @@ int nxflat_load(struct nxflat_loadinfo_s *loadinfo)
* in the file.
*/
memset((void*)(loadinfo->dspace + loadinfo->datasize),
memset((void*)(loadinfo->dspace->region + loadinfo->datasize),
0, loadinfo->bsssize);
return OK;

View file

@ -41,5 +41,5 @@ NXFLATCC = $(CC)
NXFLATCFLAGS = $(CFLAGS)
NXFLATLD = $(LD)
NXFLATLDFLAGS =
NXFLATLDFLAGS = -e main

View file

@ -43,6 +43,7 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <nxflat.h>
#include <nuttx/sched.h>
/****************************************************************************
* Pre-processor Definitions
@ -65,7 +66,7 @@ struct binary_s
main_t entrypt; /* Entry point into a program module */
FAR void *ispace; /* Memory-mapped, I-space (.text) address */
FAR void *dspace; /* Address of the allocated .data/.bss space */
FAR struct dspace_s *dspace; /* Address of the allocated .data/.bss space */
size_t isize; /* Size of the I-space region (needed for munmap) */
size_t stacksize; /* Size of the stack in bytes (unallocated) */
};

View file

@ -40,7 +40,9 @@
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nxflat.h>
#include <nuttx/sched.h>
/****************************************************************************
* Pre-processor Definitions
@ -61,29 +63,29 @@ struct nxflat_loadinfo_s
* text section instance in the system for each module.
*/
uint32 ispace; /* Address where hdr/text is loaded */
uint32 entryoffs; /* Offset from ispace to entry point */
uint32 isize; /* Size of ispace. */
uint32 ispace; /* Address where hdr/text is loaded */
uint32 entryoffs; /* Offset from ispace to entry point */
uint32 isize; /* Size of ispace. */
/* Data Space (DSpace): This region contains all information that in referenced
* as data (other than the stack which is separately allocated). There will be
* a unique instance of DSpace (and stack) for each instance of a process.
*/
uint32 dspace; /* Address where data/bss/etc. is loaded */
uint32 datasize; /* Size of data segment in dspace */
uint32 bsssize; /* Size of bss segment in dspace */
uint32 stacksize; /* Size of stack (not allocated) */
uint32 dsize; /* Size of dspace (may be large than parts) */
struct dspace_s *dspace; /* Allocated D-Space (data/bss/etc) */
uint32 datasize; /* Size of data segment in dspace */
uint32 bsssize; /* Size of bss segment in dspace */
uint32 stacksize; /* Size of stack (not allocated) */
uint32 dsize; /* Size of dspace (may be large than parts) */
/* This is temporary memory where relocation records will be loaded. */
uint32 relocstart; /* Start of array of struct flat_reloc */
uint32 reloccount; /* Number of elements in reloc array */
uint32 relocstart; /* Start of array of struct flat_reloc */
uint32 reloccount; /* Number of elements in reloc array */
/* File descriptors */
int filfd; /* Descriptor for the file being loaded */
int filfd; /* Descriptor for the file being loaded */
const struct nxflat_hdr_s *header; /* A reference to the flat file header */
};

View file

@ -161,6 +161,18 @@ typedef struct environ_s environ_t;
# define SIZEOF_ENVIRON_T(alloc) (sizeof(environ_t) + alloc - 1)
#endif
/* This structure describes a reference counted D-Space region */
struct dspace_s
{
uint32 crefs; /* This is the number of pthreads that shared the
* the same D-Space.
*/
ubyte region[1]; /* Beginning of the allocated region */
};
#define SIZEOF_DSPACE_S(n) (sizeof(struct dspace_s) - 1 + (n))
/* This is the task control block (TCB) */
struct _TCB
@ -217,7 +229,7 @@ struct _TCB
/* External Module Support ****************************************************/
#ifdef CONFIG_PIC
FAR void *picbase; /* Allocated area for .bss and .data */
FAR struct dspace_s *dspace; /* Allocated area for .bss and .data */
#endif
/* POSIX Thread Specific Data *************************************************/

View file

@ -138,9 +138,16 @@ int sched_releasetcb(FAR _TCB *tcb)
/* Delete the tasks's allocated DSpace region (external modules only) */
#ifdef CONFIG_PIC
if (tcb->picbase)
if (tcb->dspace)
{
sched_free(tcb->picbase);
if (tcb->dspace->crefs <= 1)
{
sched_free(tcb->dspace);
}
else
{
tcb->dspace->crefs--;
}
}
#endif

View file

@ -142,6 +142,43 @@ static STATUS task_assignpid(FAR _TCB *tcb)
return ERROR;
}
/****************************************************************************
* Function: task_dupdspace
*
* Description:
* When a new task or thread is created from a PIC module, then that
* module (probably) intends the task or thread to execute in the same
* D-Space. This function will duplicate the D-Space for that purpose.
*
* Parameters:
* tcb - The TCB of the new task.
*
* Returned Value:
* None
*
* Assumptions:
*
****************************************************************************/
#ifdef CONFIG_PIC
static inline void task_dupdspace(FAR _TCB *tcb)
{
FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
if (rtcb->dspace != NULL)
{
/* Copy the D-Space structure reference and increment the reference
* count on the memory. The D-Space memory will persist until the
* last thread exits (see sched_releasetcb()).
*/
tcb->dspace = rtcb->dspace;
tcb->dspace->crefs++;
}
}
#else
# define task_dupdspace(tcb)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -150,11 +187,11 @@ static STATUS task_assignpid(FAR _TCB *tcb)
* Name: task_schedsetup
*
* Description:
* This functions initializes a Task Control Block (TCB)
* in preparation for starting a new thread.
* This functions initializes a Task Control Block (TCB) in preparation
* for starting a new thread.
*
* task_schedsetup() is called from task_init(),
* task_start(), and pthread_create();
* task_schedsetup() is called from task_init(), task_start(), and
* pthread_create();
*
* Input Parameters:
* tcb - Address of the new task's TCB
@ -165,8 +202,8 @@ static STATUS task_assignpid(FAR _TCB *tcb)
* Return Value:
* OK on success; ERROR on failure.
*
* This function can only failure is it is unable to assign
* a new, unique task ID to the TCB (errno is not set).
* This function can only failure is it is unable to assign a new, unique
* task ID to the TCB (errno is not set).
*
****************************************************************************/
@ -204,6 +241,13 @@ STATUS task_schedsetup(FAR _TCB *tcb, int priority,
tcb->task_state = TSTATE_TASK_INVALID;
/* Clone the parent tasks D-Space (if it was running PIC). This
* must be done before calling up_initial_state() so that the
* state setup will take the PIC address base into account.
*/
task_dupdspace(tcb);
/* Initialize the processor-specific portion of the TCB */
up_initial_state(tcb);

View file

@ -158,9 +158,7 @@ STATUS wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
/* Save the data in the watchdog structure */
wdog->func = wdentry; /* Function to execute when delay expires */
#ifdef CONFIG_PIC
up_getpicbase(&wdog->picbase);
#endif
wdog->argc = argc;
va_start(ap, argc);