Add on-demand paging support to ARM9 prefetch abort handler
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2860 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
deb7fd1e23
commit
2d25eac7bc
@ -12,7 +12,7 @@
|
||||
<h1><big><font color="#3c34ec">
|
||||
<i>NuttX RTOS Porting Guide</i>
|
||||
</font></big></h1>
|
||||
<p>Last Updated: August 14, 2010</p>
|
||||
<p>Last Updated: August 16, 2010</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -2390,6 +2390,26 @@ extern void up_ledoff(int led);
|
||||
If CONFIG_PAGING is selected, then the following also apply:
|
||||
</p>
|
||||
<ul>
|
||||
</li>
|
||||
<li>
|
||||
<code>CONFIG_PAGING_PAGESIZE</code>:
|
||||
The size of one managed page.
|
||||
This must be a value supported by the processor's memory management unit.
|
||||
</li>
|
||||
<li>
|
||||
<code>CONFIG_PAGING_NLOCKED</code>:
|
||||
This is the number of locked pages in the memory map.
|
||||
The locked address region will then be from <code>CONFIG_DRAM_VSTART</code> through
|
||||
(<code>CONFIG_DRAM_VSTART</code> + <code>CONFIG_PAGING_PAGESIZE</code>*<code>CONFIG_PAGING_NLOCKED</code>)
|
||||
</li>
|
||||
<li>
|
||||
<code>CONFIG_PAGING_NPAGES</code>:
|
||||
The number of pages in the paged region of the memory map.
|
||||
This paged region then begins at
|
||||
(<code>CONFIG_DRAM_VSTART</code> + <code>CONFIG_PAGING_PAGESIZE</code>*<code>CONFIG_PAGING_NLOCKED</code>)
|
||||
and continues until (<code>CONFIG_DRAM_VSTART</code> +
|
||||
<code>CONFIG_PAGING_PAGESIZE</code>*(<code>CONFIG_PAGING_NLOCKED</code> + <code>CONFIG_PAGING_NPAGES</code>)
|
||||
</li>
|
||||
<li>
|
||||
<code>CONFIG_PAGING_DEFPRIO</code>:
|
||||
The default, minimum priority of the page fill worker thread.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/include/arm/irq.h
|
||||
*
|
||||
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/src/up_prefetchabort.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -41,7 +41,11 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#ifdef CONFIG_PAGING
|
||||
# include <nuttx/page.h>
|
||||
#endif
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
@ -50,6 +54,20 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
# ifndef CONFIG_PAGING_PAGESIZE
|
||||
# error "CONFIG_PAGING_PAGESIZE is not defined in your .config file"
|
||||
# endif
|
||||
# ifndef CONFIG_PAGING_NLOCKED
|
||||
# error "CONFIG_PAGING_NLOCKED is not defined in your .config file"
|
||||
# endif
|
||||
# ifndef CONFIG_PAGING_NPAGES
|
||||
# error "CONFIG_PAGING_NPAGES is not defined in your .config file"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Output debug info if stack dump is selected -- even if
|
||||
* debug is not selected.
|
||||
*/
|
||||
@ -77,7 +95,43 @@
|
||||
|
||||
void up_prefetchabort(uint32_t *regs)
|
||||
{
|
||||
lldbg("Prefetch abort at 0x%x\n", regs[REG_PC]);
|
||||
/* Save the saved processor context in current_regs where it can be accessed
|
||||
* for register dumps and possibly context switching.
|
||||
*/
|
||||
|
||||
current_regs = regs;
|
||||
PANIC(OSERR_ERREXCEPTION);
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
/* Get the (virtual) address of instruction that caused the prefetch abort.
|
||||
* When the exception occurred, this address was provide in the lr register
|
||||
* and this value was saved in the context save area as the PC at the
|
||||
* REG_R15 index.
|
||||
*
|
||||
* Check to see if this miss address is within the configured range of
|
||||
* virtual addresses.
|
||||
*/
|
||||
|
||||
if (regs[REG_R15] >= CONFIG_PAGING_PAGEDBASE &&
|
||||
regs[REG_R15] < CONFIG_PAGING_PAGEDEND)
|
||||
{
|
||||
/* Call pg_miss() to schedule the page fill. A consequences of this
|
||||
* call are:
|
||||
*
|
||||
* (1) The currently executing task will be blocked and saved on
|
||||
* on the g_waitingforfill task list.
|
||||
* (2) An interrupt-level context switch will occur so that when
|
||||
* this function returns, it will return to a different task,
|
||||
* most likely the page fill worker thread.
|
||||
* (3) The page fill worker task has been signalled and should
|
||||
* execute immediately when we return from this exception.
|
||||
*/
|
||||
|
||||
pg_miss();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
lldbg("Prefetch abort at 0x%x\n", regs[REG_PC]);
|
||||
PANIC(OSERR_ERREXCEPTION);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/arm/up_vectors.S
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -82,8 +82,8 @@ g_aborttmp:
|
||||
* Name: up_vectorirq
|
||||
*
|
||||
* Description:
|
||||
* Interrupt excetpion. Entered in IRQ mode with spsr = SVC
|
||||
* CPSR, lr = SVC PC
|
||||
* Interrupt excetpion. Entered in IRQ mode with spsr = SVC CPSR, lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorirq
|
||||
@ -91,7 +91,6 @@ g_aborttmp:
|
||||
up_vectorirq:
|
||||
/* On entry, we are in IRQ mode. We are free to use
|
||||
* the IRQ mode r13 and r14.
|
||||
*
|
||||
*/
|
||||
|
||||
ldr r13, .Lirqtmp
|
||||
@ -159,7 +158,8 @@ up_vectorirq:
|
||||
* Function: up_vectorswi
|
||||
*
|
||||
* Description:
|
||||
* SWI interrupt. We enter the SWI in SVC mode
|
||||
* SWI interrupt. We enter the SWI in SVC mode.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorswi
|
||||
@ -205,9 +205,10 @@ up_vectorswi:
|
||||
* Name: up_vectordata
|
||||
*
|
||||
* Description:
|
||||
* Data abort Exception dispatcher. Give control to data
|
||||
* abort handler. This function is entered in ABORT mode
|
||||
* with spsr = SVC CPSR, lr = SVC PC
|
||||
* This is the data abort exception dispatcher. The ARM data abort exception occurs
|
||||
* when a memory fault is detected during a data transfer. This handler saves the
|
||||
* current processor state and gives control to data abort handler. This function
|
||||
* is entered in ABORT mode with spsr = SVC CPSR, lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
@ -274,8 +275,11 @@ up_vectordata:
|
||||
* Name: up_vectorprefetch
|
||||
*
|
||||
* Description:
|
||||
* Prefetch abort exception. Entered in ABT mode with
|
||||
* spsr = SVC CPSR, lr = SVC PC
|
||||
* This is the prefetch abort exception dispatcher. The ARM prefetch abort exception
|
||||
* occurs when a memory fault is detected during an an instruction fetch. This
|
||||
* handler saves the current processor state and gives control to prefetch abort
|
||||
* handler. This function is entered in ABT mode with spsr = SVC CPSR, lr = SVC PC.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorprefetch
|
||||
@ -341,8 +345,8 @@ up_vectorprefetch:
|
||||
* Name: up_vectorundefinsn
|
||||
*
|
||||
* Description:
|
||||
* Undefined instruction entry exception. Entered in
|
||||
* UND mode, spsr = SVC CPSR, lr = SVC PC
|
||||
* Undefined instruction entry exception. Entered in UND mode, spsr = SVC CPSR,
|
||||
* lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
@ -409,6 +413,7 @@ up_vectorundefinsn:
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorfiq
|
||||
@ -419,10 +424,6 @@ up_vectorfiq:
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_userstack
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
|
@ -264,13 +264,23 @@ defconfig -- This is a configuration file similar to the Linux
|
||||
|
||||
OS setup related to on-demand paging:
|
||||
|
||||
|
||||
CONFIG_PAGING - If set =y in your configation file, this setting will
|
||||
enable the on-demand paging feature as described in
|
||||
http://www.nuttx.org/NuttXDemandPaging.html.
|
||||
enable the on-demand paging feature as described in
|
||||
http://www.nuttx.org/NuttXDemandPaging.html.
|
||||
|
||||
If CONFIG_PAGING is selected, then the following also apply:
|
||||
|
||||
CONFIG_PAGING_PAGESIZE - The size of one managed page. This must
|
||||
be a value supported by the processor's memory management unit.
|
||||
CONFIG_PAGING_NLOCKED - This is the number of locked pages in the
|
||||
memory map. The locked address region will then be from
|
||||
CONFIG_DRAM_VSTART through (CONFIG_DRAM_VSTART +
|
||||
CONFIG_PAGING_PAGESIZE*CONFIG_PAGING_NLOCKED)
|
||||
CONFIG_PAGING_NPAGES - The number of pages in the paged region of
|
||||
the memory map. This paged region then begins at (CONFIG_DRAM_VSTART +
|
||||
CONFIG_PAGING_PAGESIZE*CONFIG_PAGING_NLOCKED) and continues until
|
||||
(CONFIG_DRAM_VSTART + CONFIG_PAGING_PAGESIZE*(CONFIG_PAGING_NLOCKED +
|
||||
CONFIG_PAGING_NPAGES)
|
||||
CONFIG_PAGING_DEFPRIO - The default, minimum priority of the page fill
|
||||
worker thread. The priority of the page fill work thread will be boosted
|
||||
boosted dynmically so that it matches the priority of the task on behalf
|
||||
@ -285,7 +295,7 @@ defconfig -- This is a configuration file similar to the Linux
|
||||
CONFIG_PAGING_TIMEOUT_TICKS - If defined, the implementation will monitor
|
||||
the (asynchronous) page fill logic. If the fill takes longer than this
|
||||
number if microseconds, then a fatal error will be declared.
|
||||
Default: No timeouts monitored.
|
||||
Default: No timeouts monitored.
|
||||
|
||||
The following can be used to disable categories of APIs supported
|
||||
by the OS. If the compiler supports weak functions, then it
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
|
||||
@ -51,6 +52,42 @@
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
/* CONFIG_PAGING_PAGESIZE - The size of one managed page. This must be a
|
||||
* value supported by the processor's memory management unit.
|
||||
* CONFIG_PAGING_NLOCKED - This is the number of locked pages in the memory
|
||||
* map. The locked address region will then be from:
|
||||
*/
|
||||
|
||||
#define CONFIG_PAGING_LOCKEDBASE CONFIG_DRAM_VSTART
|
||||
#define CONFIG_PAGING_LOCKEDSIZE (CONFIG_PAGING_PAGESIZE*CONFIG_PAGING_NLOCKED)
|
||||
#define CONFIG_PAGING_LOCKEDEND (CONFIG_PAGING_LOCKEDBASE + CONFIG_PAGING_LOCKEDSIZE)
|
||||
|
||||
/* CONFIG_PAGING_NPAGES - The number of pages in the paged region of the
|
||||
* memory map. This paged region then begins and ends at:
|
||||
*/
|
||||
|
||||
#define CONFIG_PAGING_PAGEDBASE CONFIG_PAGING_LOCKEDEND
|
||||
#define CONFIG_PAGING_PAGEDSIZE (CONFIG_PAGING_PAGESIZE*CONFIG_PAGING_NPAGES)
|
||||
#define CONFIG_PAGING_PAGEDEND (CONFIG_PAGING_PAGEDBASE + CONFIG_PAGING_PAGEDSIZE)
|
||||
|
||||
/* CONFIG_PAGING_DEFPRIO - The default, minimum priority of the page fill
|
||||
* worker thread. The priority of the page fill work thread will be boosted
|
||||
* boosted dynmically so that it matches the priority of the task on behalf
|
||||
* of which it peforms the fill. This defines the minimum priority that
|
||||
* will be used. Default: 50.
|
||||
* CONFIG_PAGING_STACKSIZE - Defines the size of the allocated stack
|
||||
* for the page fill worker thread. Default: 1024.
|
||||
* CONFIG_PAGING_BLOCKINGFILL - The architecture specific up_fillpage()
|
||||
* function may be blocking or non-blocking. If defined, this setting
|
||||
* indicates that the up_fillpage() implementation will block until the
|
||||
* transfer is completed. Default: Undefined (non-blocking).
|
||||
* CONFIG_PAGING_TIMEOUT_TICKS - If defined, the implementation will monitor
|
||||
* the (asynchronous) page fill logic. If the fill takes longer than this
|
||||
* number if microseconds, then a fatal error will be declared.
|
||||
* Default: No timeouts monitored.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
@ -189,15 +189,18 @@ const tasklist_t g_tasklisttable[NUM_TASK_STATES] =
|
||||
{ &g_readytorun, true }, /* TSTATE_TASK_READYTORUN */
|
||||
{ &g_readytorun, true }, /* TSTATE_TASK_RUNNING */
|
||||
{ &g_inactivetasks, false }, /* TSTATE_TASK_INACTIVE */
|
||||
{ &g_waitingforsemaphore, true }, /* TSTATE_WAIT_SEM */
|
||||
{ &g_waitingforsemaphore, true } /* TSTATE_WAIT_SEM */
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
{ &g_waitingforsignal, false }, /* TSTATE_WAIT_SIG */
|
||||
,
|
||||
{ &g_waitingforsignal, false } /* TSTATE_WAIT_SIG */
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_MQUEUE
|
||||
,
|
||||
{ &g_waitingformqnotempty, true }, /* TSTATE_WAIT_MQNOTEMPTY */
|
||||
{ &g_waitingformqnotfull, true } /* TSTATE_WAIT_MQNOTFULL */
|
||||
#endif
|
||||
#ifdef CONFIG_PAGING
|
||||
,
|
||||
{ &g_waitingforfill, true } /* TSTATE_WAIT_PAGEFILL */
|
||||
#endif
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user