summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-08-17 01:37:39 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-08-17 01:37:39 +0000
commit19e95ff894d1861cd7406a45dfd36721601d6385 (patch)
tree34e9a54c4a83d76a79b4ae6556b57551f3bf0a52
parentb082d08f6137b60e02a646781c2a3d2b34ffab1f (diff)
downloadpx4-nuttx-19e95ff894d1861cd7406a45dfd36721601d6385.tar.gz
px4-nuttx-19e95ff894d1861cd7406a45dfd36721601d6385.tar.bz2
px4-nuttx-19e95ff894d1861cd7406a45dfd36721601d6385.zip
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
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html22
-rw-r--r--nuttx/arch/arm/include/arm/irq.h2
-rw-r--r--nuttx/arch/arm/src/arm/up_prefetchabort.c60
-rw-r--r--nuttx/arch/arm/src/arm/up_vectors.S33
-rw-r--r--nuttx/configs/README.txt18
-rwxr-xr-xnuttx/include/nuttx/page.h37
-rw-r--r--nuttx/sched/os_start.c7
7 files changed, 152 insertions, 27 deletions
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index 6150823fb..13a4775ef 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -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.
diff --git a/nuttx/arch/arm/include/arm/irq.h b/nuttx/arch/arm/include/arm/irq.h
index 38ea20553..6e361d4f6 100644
--- a/nuttx/arch/arm/include/arm/irq.h
+++ b/nuttx/arch/arm/include/arm/irq.h
@@ -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
diff --git a/nuttx/arch/arm/src/arm/up_prefetchabort.c b/nuttx/arch/arm/src/arm/up_prefetchabort.c
index 3d6f5b8d8..13d4f5a07 100644
--- a/nuttx/arch/arm/src/arm/up_prefetchabort.c
+++ b/nuttx/arch/arm/src/arm/up_prefetchabort.c
@@ -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);
+ }
}
diff --git a/nuttx/arch/arm/src/arm/up_vectors.S b/nuttx/arch/arm/src/arm/up_vectors.S
index 987b875ce..6072e6387 100644
--- a/nuttx/arch/arm/src/arm/up_vectors.S
+++ b/nuttx/arch/arm/src/arm/up_vectors.S
@@ -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
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index 23ea00bd3..335ee0468 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -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
diff --git a/nuttx/include/nuttx/page.h b/nuttx/include/nuttx/page.h
index fc8ec989d..1e5ed4449 100755
--- a/nuttx/include/nuttx/page.h
+++ b/nuttx/include/nuttx/page.h
@@ -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
****************************************************************************/
diff --git a/nuttx/sched/os_start.c b/nuttx/sched/os_start.c
index 9e299a946..6ca865fbc 100644
--- a/nuttx/sched/os_start.c
+++ b/nuttx/sched/os_start.c
@@ -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
};