From cdbb7040cc2ba10d5c86fccc448660a401dad7b9 Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 11 Dec 2012 18:04:04 +0000 Subject: Add support for the Z180 MMU and generic hooks for processes git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5428 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/ChangeLog | 3 + nuttx/Documentation/NuttxPortingGuide.html | 5 +- nuttx/Documentation/README.html | 5 +- nuttx/README.txt | 2 +- nuttx/arch/Kconfig | 9 + nuttx/arch/z80/Kconfig | 54 +++- nuttx/arch/z80/include/z180/irq.h | 83 ++++-- nuttx/arch/z80/src/z180/Kconfig | 101 ++++++- nuttx/arch/z80/src/z180/Make.defs | 25 +- nuttx/arch/z80/src/z180/z180_head.asm | 16 +- nuttx/arch/z80/src/z180/z180_mmu.c | 405 ++++++++++++++++++++++++++++ nuttx/arch/z80/src/z180/z180_mmu.h | 149 ++++++++++ nuttx/arch/z80/src/z180/z180_mmu.txt | 114 ++++++++ nuttx/binfmt/Kconfig | 5 + nuttx/configs/README.txt | 3 + nuttx/configs/pic32-starterkit/src/up_spi.c | 4 +- nuttx/configs/pic32mx7mmb/src/up_spi.c | 4 +- nuttx/include/nuttx/arch.h | 170 +++++++++--- nuttx/mm/mm_graninit.c | 1 - nuttx/sched/Kconfig | 10 +- 20 files changed, 1057 insertions(+), 111 deletions(-) create mode 100644 nuttx/arch/z80/src/z180/z180_mmu.c create mode 100644 nuttx/arch/z80/src/z180/z180_mmu.h create mode 100644 nuttx/arch/z80/src/z180/z180_mmu.txt (limited to 'nuttx') diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 7a2a2cbff..7e3b2a43f 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3777,4 +3777,7 @@ are just clones of z80 header files. * arch/z80/src/z180: Add source files for z180 chips. Initial versions are just clones of z80 source files. + * include/nuttx/arch.h: Add address environment control interfaces (for use + with CPUs the provide MCUs and support process-like address environments). + * arch/z80/src/z180/z180_mmu.*: Add MMU support for z180 tasks. diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html index c3f6286df..0ed46cba1 100644 --- a/nuttx/Documentation/NuttxPortingGuide.html +++ b/nuttx/Documentation/NuttxPortingGuide.html @@ -12,7 +12,7 @@

NuttX RTOS Porting Guide

-

Last Updated: October 30, 2012

+

Last Updated: December 11, 2012

@@ -3697,6 +3697,9 @@ void (*notify)(FAR struct pm_callback_s *cb, enum pm_state_e pmstate);
  • CONFIG_ARCH_IRQPRIO: Define if the architecture supports prioritization of interrupts and the up_prioritize_irq() API.
  • +
  • CONFIG_ADDRENV: + The CPU supports an MMU and CPU port supports provision of address + environments for tasks (making the, perhaps, processes).
  • diff --git a/nuttx/Documentation/README.html b/nuttx/Documentation/README.html index ef1803143..7dd23ac3d 100644 --- a/nuttx/Documentation/README.html +++ b/nuttx/Documentation/README.html @@ -8,7 +8,7 @@

    NuttX README Files

    -

    Last Updated: October 27, 2012

    +

    Last Updated: December 11, 2012

    @@ -49,7 +49,8 @@ | | | |- src/z80 | | | | `- README.txt | | | `- src/z180 - | | | `- README.txt + | | | |- README.txt + | | | `- z180_mmu.txt | | `- README.txt | |- configs/ | | |- amber/ diff --git a/nuttx/README.txt b/nuttx/README.txt index c94947279..55f42339c 100644 --- a/nuttx/README.txt +++ b/nuttx/README.txt @@ -750,7 +750,7 @@ nuttx | `- z80/ | | `- src/ | | |- z80/README.txt - | | `- z180/README.txt + | | `- z180/README.txt, z180_mmu.txt | `- README.txt |- configs/ | |- amber/ diff --git a/nuttx/arch/Kconfig b/nuttx/arch/Kconfig index 6e55a5744..f19228143 100644 --- a/nuttx/arch/Kconfig +++ b/nuttx/arch/Kconfig @@ -9,6 +9,7 @@ choice config ARCH_8051 bool "8051" + select CUSTOM_STACK ---help--- Intel 8051 architectures and derivaties @@ -115,6 +116,14 @@ config ARCH_IRQPRIO bool default n +config CUSTOM_STACK + bool + default n + +config ADDRENV + bool + default n + config ARCH_STACKDUMP bool "Dump stack on assertions" default n diff --git a/nuttx/arch/z80/Kconfig b/nuttx/arch/z80/Kconfig index 91aedba8f..4dcc8255e 100644 --- a/nuttx/arch/z80/Kconfig +++ b/nuttx/arch/z80/Kconfig @@ -17,6 +17,7 @@ config ARCH_CHIP_Z8018006VSG bool "Z8018006VSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z80180 @@ -24,6 +25,7 @@ config ARCH_CHIP_Z8018010VSG bool "Z8018010VSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z80180 @@ -31,6 +33,7 @@ config ARCH_CHIP_Z8018008VSG bool "Z8018008VSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z80180 @@ -38,6 +41,7 @@ config ARCH_CHIP_Z8018010FSG bool "Z8018010FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 80-pin QFP (11 pins N/C) Z80180 @@ -45,6 +49,7 @@ config ARCH_CHIP_Z8018008VEG bool "Z8018008VEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z80180 @@ -52,6 +57,7 @@ config ARCH_CHIP_Z8018006VEG bool "Z8018006VEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z80180 @@ -59,6 +65,7 @@ config ARCH_CHIP_Z8018006PSG bool "Z8018006PSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 64-pin DIP 6 MHz 5V Z80180 @@ -66,6 +73,7 @@ config ARCH_CHIP_Z8018008FSG bool "Z8018008FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 80-pin QFP (11 pins N/C) 8MHz 5V Z80180 @@ -73,6 +81,7 @@ config ARCH_CHIP_Z8018010PSG bool "Z8018010PSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 64-pin DIP 10MHz 5V Z80180 @@ -80,6 +89,7 @@ config ARCH_CHIP_Z8018006PEG bool "Z8018006PEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 64-pin DIP 6MHz 5V Z80180 @@ -87,6 +97,7 @@ config ARCH_CHIP_Z8018010VEG bool "Z8018010VEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- 68-pin PLCC 10MHz 5V Z80180 @@ -94,6 +105,7 @@ config ARCH_CHIP_Z8018010PEG bool "Z8018010PEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 64-pin DIP 10MHz 5V Z80180 @@ -101,6 +113,7 @@ config ARCH_CHIP_Z8018008PSG bool "Z8018008PSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- Z180: 64-pin DIP 8MHz 5V Z80180 @@ -108,33 +121,39 @@ config ARCH_CHIP_Z8018006FSG bool "Z8018006FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV ---help--- - 80-pin QFP (11 pins N/C) 6MHz 5V Z80180 + Z180: 80-pin QFP (11 pins N/C) 6MHz 5V Z80180 config ARCH_CHIP_Z8018000XSO bool "Z8018000XSO" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV config ARCH_CHIP_Z8018010FEG bool "Z8018010FEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV config ARCH_CHIP_Z8018000WSO bool "Z8018000WSO" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV config ARCH_CHIP_Z8018008PEG bool "Z8018008PEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80180 + select ADDRENV config ARCH_CHIP_Z8018110FEG bool "Z8018110FEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80181 + select ADDRENV ---help--- Z180: 100-pin QFP Z80181 @@ -142,6 +161,7 @@ config ARCH_CHIP_Z8018233FSG bool "Z8018233FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80182 + select ADDRENV ---help--- 100-pin QFP Z80182 @@ -149,6 +169,7 @@ config ARCH_CHIP_Z8018220AEG bool "Z8018220AEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80182 + select ADDRENV ---help--- Z180: 100-pin LQFP 20MHz 5V Z80182 @@ -156,6 +177,7 @@ config ARCH_CHIP_Z8018216FSG bool "Z8018216FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80182 + select ADDRENV ---help--- Z180: 100-pin QFP 16MHz 5V Z80182 @@ -163,6 +185,7 @@ config ARCH_CHIP_Z8018216ASG bool "Z8018216ASG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80182 + select ADDRENV ---help--- Z180: 100-pin LQFP Z80182 @@ -170,6 +193,7 @@ config ARCH_CHIP_Z8018233ASG bool "Z8018233ASG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80182 + select ADDRENV ---help--- Z180: 100-pin LQFP 33MHz 5V Z80182 @@ -177,6 +201,7 @@ config ARCH_CHIP_Z8019520FSG bool "Z8019520FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80195 + select ADDRENV ---help--- Z180: 100-pin QFP 20MHz 5V Z80195 @@ -184,6 +209,7 @@ config ARCH_CHIP_Z8019533FSG bool "Z8019533FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z80195 + select ADDRENV ---help--- Z180: 100-pin QFP 33MHz 5V Z80195 @@ -191,6 +217,7 @@ config ARCH_CHIP_Z8L18020VSG bool "Z8L18020VSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8L180 + select ADDRENV ---help--- Z180: 68-pinn PLCC Z8L180 @@ -198,6 +225,7 @@ config ARCH_CHIP_Z8L18020FSG bool "Z8L18020FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8L180 + select ADDRENV ---help--- Z180: 80-pin GFP 20MHz 3.3V Z8L180 @@ -205,11 +233,13 @@ config ARCH_CHIP_Z8L18020PSG bool "Z8L18020PSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8L180 + select ADDRENV config ARCH_CHIP_Z8L18220ASG bool "Z8L18220ASG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8L182 + select ADDRENV ---help--- Z180: 100-pin LQFP Z8L182 @@ -217,6 +247,7 @@ config ARCH_CHIP_Z8L18220FSG bool "Z8L18220FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8L182 + select ADDRENV ---help--- 100-pin QFP 20MHz 3.3V Z8L182 @@ -224,11 +255,13 @@ config ARCH_CHIP_Z8L18220AEG bool "Z8L18220AEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8L182 + select ADDRENV config ARCH_CHIP_Z8S18020VSG bool "Z8S18020VSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z8S180 @@ -236,6 +269,7 @@ config ARCH_CHIP_Z8S18020VSG1960 bool "Z8S18020VSG1960" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z8S180 @@ -243,6 +277,7 @@ config ARCH_CHIP_Z8S18033VSG bool "Z8S18033VSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z8S180 @@ -250,6 +285,7 @@ config ARCH_CHIP_Z8S18010FSG bool "Z8S18010FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- 80-pin QFP Z8S180 @@ -257,6 +293,7 @@ config ARCH_CHIP_Z8S18010VEG bool "Z8S18010VEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z8S180 @@ -264,6 +301,7 @@ config ARCH_CHIP_Z8S18020VEG bool "Z8S18020VEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z8S180 @@ -271,6 +309,7 @@ config ARCH_CHIP_Z8S18010VSG bool "Z8S18010VSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 68-pin PLCC Z8S180 @@ -278,6 +317,7 @@ config ARCH_CHIP_Z8S18020PSG bool "Z8S18020PSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- 64-pin DIP 10Mhz 5V Z8S180 @@ -285,6 +325,7 @@ config ARCH_CHIP_Z8S18033FSG bool "Z8S18033FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 80-pin QFP 33MHz 5V Z8S180 @@ -292,6 +333,7 @@ config ARCH_CHIP_Z8S18033FEG bool "Z8S18033FEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 80-pin QFP 33MHz 5V Z8S180 @@ -299,13 +341,15 @@ config ARCH_CHIP_Z8S18020FSG bool "Z8S18020FSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- - 80-pin QFP 20MHz 5V Z8S180 + Z180: 80-pin QFP 20MHz 5V Z8S180 config ARCH_CHIP_Z8S18033VEG bool "Z8S18033VEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- Z180: 68-pin PLCC 33MHz 5V Z8S180 @@ -313,23 +357,27 @@ config ARCH_CHIP_Z8S18010PSG bool "Z8S18010PSG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV ---help--- - 64-pin DIP 10MHz 5V Z8S180 + Z180: 64-pin DIP 10MHz 5V Z8S180 config ARCH_CHIP_Z8S18020FEG bool "Z8S18020FEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV config ARCH_CHIP_Z8S18010PEG bool "Z8S18010PEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV config ARCH_CHIP_Z8S18010FEG bool "Z8S18010FEG" select ARCH_CHIP_Z180 select ARCH_CHIP_Z8S180 + select ADDRENV config ARCH_CHIP_Z8F6403 bool "Z8F6403" diff --git a/nuttx/arch/z80/include/z180/irq.h b/nuttx/arch/z80/include/z180/irq.h index 3f058591f..a72cf4708 100644 --- a/nuttx/arch/z80/include/z180/irq.h +++ b/nuttx/arch/z80/include/z180/irq.h @@ -55,17 +55,17 @@ /* Z180 Interrupts */ -#define Z180_RST0 (0) -#define Z180_RST1 (1) -#define Z180_RST2 (2) -#define Z180_RST3 (3) -#define Z180_RST4 (4) -#define Z180_RST5 (5) -#define Z180_RST6 (6) -#define Z180_RST7 (7) +#define Z180_RST0 (0) +#define Z180_RST1 (1) +#define Z180_RST2 (2) +#define Z180_RST3 (3) +#define Z180_RST4 (4) +#define Z180_RST5 (5) +#define Z180_RST6 (6) +#define Z180_RST7 (7) #define Z180_IRQ_SYSTIMER Z180_RST7 -#define NR_IRQS (8) +#define NR_IRQS (8) /* IRQ Stack Frame Format * @@ -73,18 +73,33 @@ * in the TCB to many context switches. */ -#define XCPT_I (0) /* Offset 0: Saved I w/interrupt state in carry */ -#define XCPT_BC (1) /* Offset 1: Saved BC register */ -#define XCPT_DE (2) /* Offset 2: Saved DE register */ -#define XCPT_IX (3) /* Offset 3: Saved IX register */ -#define XCPT_IY (4) /* Offset 4: Saved IY register */ -#define XCPT_SP (5) /* Offset 5: Offset to SP at time of interrupt */ -#define XCPT_HL (6) /* Offset 6: Saved HL register */ -#define XCPT_AF (7) /* Offset 7: Saved AF register */ -#define XCPT_PC (8) /* Offset 8: Offset to PC at time of interrupt */ - -#define XCPTCONTEXT_REGS (9) -#define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS) +#define XCPT_I (0) /* Offset 0: Saved I w/interrupt state in carry */ +#define XCPT_BC (1) /* Offset 1: Saved BC register */ +#define XCPT_DE (2) /* Offset 2: Saved DE register */ +#define XCPT_IX (3) /* Offset 3: Saved IX register */ +#define XCPT_IY (4) /* Offset 4: Saved IY register */ +#define XCPT_SP (5) /* Offset 5: Offset to SP at time of interrupt */ +#define XCPT_HL (6) /* Offset 6: Saved HL register */ +#define XCPT_AF (7) /* Offset 7: Saved AF register */ +#define XCPT_PC (8) /* Offset 8: Offset to PC at time of interrupt */ + +#define XCPTCONTEXT_REGS (9) +#define XCPTCONTEXT_SIZE (2 * XCPTCONTEXT_REGS) + +/* Interrupt vectors (offsets) for Z180 internal interrupts */ + +#define Z180_INT1_VECTOR 0x00 /* External /INT1 */ +#define Z180_INT2_VECTOR 0x02 /* External /INT2 */ +#define Z180_PRT0_VECTOR 0x04 /* PRT channel 0 */ +#define Z180_PRT1_VECTOR 0x06 /* PRT channel 1 */ +#define Z180_DMA0_VECTOR 0x08 /* DMA channel 0 */ +#define Z180_DMA1_VECTOR 0x0a /* DMA Channel 1 */ +#define Z180_CSIO_VECTOR 0x0c /* Clocked serial I/O */ +#define Z180_ASCI0_VECTOR 0x0e /* Async channel 0 */ +#define Z180_ASCI1_VECTOR 0x10 /* Async channel 1 */ +#define Z180_INCAP_VECTOR 0x12 /* Input capture */ +#define Z180_OUTCMP_VECTOR 0x14 /* Output compare */ +#define Z180_TIMOV_VECTOR 0x16 /* Timer overflow */ /**************************************************************************** * Public Types @@ -96,10 +111,34 @@ typedef uint16_t chipreg_t; -/* This struct defines the way the registers are stored. */ +/* Common Area 1 holds the code and data that is unique to a particular task + * and shared by all pthreads created from that task. Each task will then + * have its own copy of struct z180_cbr_s. This structure is created with + * a reference count of one when the task is created. + * + * When the task creates additional threads, the reference count is + * incremented and the CBR value is shared. When each thread exits, the + * reference count id decremented. When the reference count is decremented, + * the physical memory underlying the CBR is finally released. + */ + +struct z180_cbr_s +{ + uint8_t cbr; /* The CBR value used by the thread */ + uint8_t crefs; /* The number of threads sharing this CBR value */ + uint8_t pages; /* The number of 4KB pages of physical memory in the allocation */ +}; + +/* This struct defines the way the registers and z180-state information are + * stored. + */ struct xcptcontext { + /* CBR allocation */ + + FAR struct z180_cbr_s *cbr; + /* Register save area */ chipreg_t regs[XCPTCONTEXT_REGS]; diff --git a/nuttx/arch/z80/src/z180/Kconfig b/nuttx/arch/z80/src/z180/Kconfig index 4eafa8da8..58abbd6f2 100644 --- a/nuttx/arch/z80/src/z180/Kconfig +++ b/nuttx/arch/z80/src/z180/Kconfig @@ -21,30 +21,115 @@ config Z180_TOOLCHAIN_SDCCW endchoice config LINKER_HOME_AREA - hex "Start of _HOME area" + hex "Physical start of _HOME area" default 0x0000 ---help--- - Start of the linker HOME area. Default: 0x0000 + Physical address of the start of the linker HOME area. Default: 0x0000 config LINKER_CODE_AREA - hex "Start of _CODE area" + hex "Physical start of _CODE area" default 0x0200 ---help--- - Start of the linker _CODE area. Default: 0x0200 + Physical address of the start of the linker _CODE area. Default: 0x0200 config LINKER_DATA_AREA - hex "Start of _DATA area" + hex "Physical start of _DATA area" default 0x8000 ---help--- - Start of the linker _DATA area. Default: 0x8000 + Physical address of the start of the linker _DATA area. Default: 0x8000 config LINKER_ROM_AT_0000 - bool "ROM at 0x0000" + bool "ROM at Physical 0x0000" default n ---help--- - Some architectures may have ROM located at address zero. In this + Some architectures may have ROM located at physical address zero. In this case, a special version of the "head" file must be used. +config Z180_BANKAREA_VIRTBASE + hex "Virtual Start of Bank Area" + default 0x8000 + ---help--- + This setting provides the virtual address of the start of the Bank Area. + NOTE that 0x0000 <= Z180_BANKAREA_BASE <= Z180_COMMONAREA_BASE is required! + Default: 0x8000 + + NuttX Memory Organization: + + Common Area 0: This area holds the common NuttX code that is + directly call-able from all application threads. Common Area + always starts at virtual address 0x0000 and extends to the + Bank Area + + Base Area: This area holds the common NuttX data (including the + share-able heap) that is accessible from all applications and + extends to Common Area 1. + + NOTE: That is execution from RAM, the common NuttX code and + data may be contiguous and lie in the same region (either + Common Area 0 or the Bank Area). The two regions above would + apply in a ROM'ed system, where Common Area 1 is ROM and the + Base Area is RAM. + + Common Area 1: This area holds the code and data that is unique + to a particular task. his area extends to the end of the virtual + address space. All tasks share the same virtual Common Area 2 + virtual address (but each has a unique mapping to different, + underlying physical addresses). + +config Z180_BANKAREA_PHYSBASE + hex "Physical Start of Bank Area" + default 0x08000 + ---help--- + This setting provides the physical address of the start of the Bank Area. + Default: 0x08000 + +config Z180_COMMON1AREA_VIRTBASE + hex "Virtual Start of Common Area 1" + default 0xc000 + ---help--- + This setting provides the virtual address of the start of the Common + Area 1. NOTE that 0x0000 <= Z180_BANKAREA_BASE <= Z180_COMMONAREA_BASE + is required! Default: 0xc000 + + NuttX Memory Organization: + + Common Area 0: This area holds the common NuttX code that is + directly call-able from all application threads. Common Area + always starts at virtual address 0x0000 and extends to the + Bank Area + + Base Area: This area holds the common NuttX data (including the + share-able heap) that is accessible from all applications and + extends to Common Area 1. + + NOTE: That is execution from RAM, the common NuttX code and + data may be contiguous and lie in the same region (either + Common Area 0 or the Bank Area). The two regions above would + apply in a ROM'ed system, where Common Area 1 is ROM and the + Base Area is RAM. + + Common Area 1: This area holds the code and data that is unique + to a particular task. his area extends to the end of the virtual + address space. All tasks share the same virtual Common Area 2 + virtual address (but each has a unique mapping to different, + underlying physical addresses). + +config Z180_PHYSHEAP_START + hex "Physical Start of Free Memory" + default 0x0c000 + ---help--- + This setting provides the physical address of the start of free physical + memory that will be used to allocate memory for tasks (Common Area 1). + Default: 0x0c000 + +config Z180_PHYSHEAP_END + hex "Physical End(+1) of Free Memory" + default 0x100000 + ---help--- + This setting provides the physical address of the end(+1) of free physical + memory that will be used to allocate memory for tasks (Common Area 1). + Default: 0x100000 + config ARCH_HAVEHEAD bool "Board-specific Head File" default n diff --git a/nuttx/arch/z80/src/z180/Make.defs b/nuttx/arch/z80/src/z180/Make.defs index d371a5d22..069f36204 100644 --- a/nuttx/arch/z80/src/z180/Make.defs +++ b/nuttx/arch/z80/src/z180/Make.defs @@ -35,21 +35,20 @@ ifeq ($(CONFIG_ARCH_HAVEHEAD),) ifeq ($(CONFIG_LINKER_ROM_AT_0000),y) -HEAD_ASRC = z180_rom.asm +HEAD_ASRC = z180_rom.asm else -HEAD_ASRC = z180_head.asm +HEAD_ASRC = z180_head.asm endif endif -CMN_ASRCS = -CMN_CSRCS = up_initialize.c up_allocateheap.c up_createstack.c \ - up_releasestack.c up_interruptcontext.c up_blocktask.c \ - up_unblocktask.c up_exit.c up_releasepending.c \ - up_reprioritizertr.c up_idle.c up_assert.c up_doirq.c \ - up_mdelay.c up_udelay.c up_usestack.c - -CHIP_ASRCS = z180_saveusercontext.asm z180_restoreusercontext.asm -CHIP_CSRCS = z180_initialstate.c z180_io.c z180_irq.c z180_copystate.c \ - z180_schedulesigaction.c z180_sigdeliver.c \ - z180_registerdump.c +CMN_ASRCS = +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_createstack.c +CMN_CSRCS += up_doirq.c up_exit.c up_idle.c up_initialize.c +CMN_CSRCS += up_interruptcontext.c up_mdelay.c up_releasepending.c +CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_unblocktask.c +CMN_CSRCS += up_udelay.c up_usestack.c +CHIP_ASRCS = z180_restoreusercontext.asm z180_saveusercontext.asm +CHIP_CSRCS = z180_copystate.c z180_initialstate.c z180_io.c z180_irq.c +CHIP_CSRCS += z180_mmu.c z180_registerdump.c z180_schedulesigaction.c +CHIP_CSRCS += z180_sigdeliver.c diff --git a/nuttx/arch/z80/src/z180/z180_head.asm b/nuttx/arch/z80/src/z180/z180_head.asm index ca064160a..ddd0283e9 100644 --- a/nuttx/arch/z80/src/z180/z180_head.asm +++ b/nuttx/arch/z80/src/z180/z180_head.asm @@ -60,8 +60,9 @@ ; Global symbols used ;************************************************************************** - .globl _os_start ; OS entry point - .globl _up_doirq ; Interrupt decoding logic + .globl _os_start ; OS entry point + .globl _up_doirq ; Interrupt decoding logic + .globl z180_mmu_lowinit ; MMU initialization logic ;************************************************************************** ; Reset entry point @@ -70,9 +71,9 @@ .area _HEADER (ABS) .org 0x0000 - di ; Disable interrupts - im 1 ; Set interrupt mode 1 - jr _up_reset ; And boot the system + di ; Disable interrupts + im 1 ; Set interrupt mode 1 + jr _up_reset ; And boot the system ;************************************************************************** ; Other reset handlers @@ -168,6 +169,11 @@ _up_reset: ld SP, #CONFIG_STACK_END ; Set stack pointer + ; Configure the MMU so that things will lie at the addresses that we + ; expect them to + + call z180_mmu_lowinit ; Initialize the MMU + ; Performed initialization unique to the SDCC toolchain call gsinit ; Initialize the data section diff --git a/nuttx/arch/z80/src/z180/z180_mmu.c b/nuttx/arch/z80/src/z180/z180_mmu.c new file mode 100644 index 000000000..c71f59755 --- /dev/null +++ b/nuttx/arch/z80/src/z180/z180_mmu.c @@ -0,0 +1,405 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_mmu.c + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* See arch/z80/src/z180/z180_mmu.txt for additional information */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "z180_mmu.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_ADDRENV +# warning "OS address environment support is required (CONFIG_ADDRENV)" +#endif + +#ifndef CONFIG_GRAN +# warning "This file requires the granual allocator (CONFIG_GRAN)" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifndef CONFIG_GRAN_SINGLE +static GRAN_HANDLE g_physhandle; +#endif +static struct z180_cbr_s g_cbrs[CONFIG_MAX_TASKS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_mmu_findcbr + * + * Description: + * Find an unused struture in g_cbrs (i.e., one with reference count == 0). + * If a structure is found, its reference count is set to one and a pointer + * to the structure is returned. + * + ****************************************************************************/ + +static FAR struct z180_cbr_s *z180_mmu_findcbr(void) +{ + int i; + + for (i = 0; i < CONFIG_MAX_TASKS; i++) + { + FAR struct z180_cbr_s *cbr = &g_cbrs[i]; + if (cbr->crefs == 0) + { + cbr->crefs = 1; + return cbr; + } + } + + return NULL; +} + +/**************************************************************************** + * Name: z180_mmu_freecbr + * + * Description: + * Free a struture in g_cbrs by setting its reference count to 0; + * + ****************************************************************************/ + +#define z180_mmu_freecbr(cbr) (cbr)->crefs = 0 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_mmu_lowinit + * + * Description: + * Low-level, power-up initialization of the z180 MMU. this must be + * called very early in the boot process to get the basic operating + * memory configuration correct. This function does *not* perform all + * necessray MMU initialization... only the basics needed at power-up. + * z180_mmu_init() must be called later to complete the entire MMU + * initialization. + * + ****************************************************************************/ + +void z180_mmu_lowinit(void) __naked +{ + __asm + ld c, #Z180_MMU_CBR ; port + ld a, #Z180_CBAR_VALUE ; value + out (c), a + + ld c, #Z180_MMU_BBR ; port + ld a, #Z180_BBR_VALUE ; value + out (c), a + __endasm; +} + +/**************************************************************************** + * Name: z180_mmu_init + * + * Description: + * Perform higher level initializatin of the MMU and physical memory + * memory management logic. + * + ****************************************************************************/ + +int z180_mmu_init(void) +{ + /* Here we use the granule allocator as a page allocator. We lie and + * say that 1 page is 1 byte. + */ + +#ifdef CONFIG_GRAN_SINGLE +return gran_initialize((FAR void *)Z180_PHYSHEAP_STARTPAGE, + Z180_PHYSHEAP_NPAGES, 0, 0); +#else +g_physhandle = gran_initialize((FAR void *)Z180_PHYSHEAP_STARTPAGE, + Z180_PHYSHEAP_NPAGES, 0, 0); +return g_physhandle ? OK : -ENOMEM; +#endif +} + +/**************************************************************************** + * Name: up_addrenv_create + * + * Description: + * This function is called from the binary loader logic when a new + * task is created in RAM in order to instantiate an address environment for + * the task. + * + * Input Parameters: + * tcb - The TCB of the task needing the address environment. + * envsize - The size (in bytes) of the address environment needed by the + * task. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int up_addrenv_create(FAR _TCB *tcb, size_t envsize) +{ + FAR struct z180_cbr_s *cbr; + irqstate_t flags; + uintptr_t alloc; + unsigned int npages; + int ret; + + /* Make sure that there is no address environment in place on this TCB */ + + DEBUGASSERT(tcb->xcp.cbr == NULL); + + /* Convert the size from bytes to numbers of pages */ + + npages = PHYS_ALIGNUP(envsize); + if (npages < 1) + { + /* No address environment... but I suppose that is not an error */ + + sdbg("ERROR: npages is zero\n"); + return OK; + } + + /* Allocate a structure in the common .bss to hold information about the + * task's address environment. NOTE that this is not a part of the TCB, + * but rather a break-away structure that can be shared by the task as + * well as other threads. That is necessary because the life of the + * address of environment might be longer than the life of the task. + */ + + flags = irqsave(); + cbr = z180_mmu_findcbr(); + if (!cbr) + { + sdbg("ERROR: No free CBR structures\n"); + ret = -ENOMEM; + goto errout_with_irq + } + + /* Now allocate the physical memory to back up the address environment */ + + +#ifdef CONFIG_GRAN_SINGLE + alloc = (uintptr_t)gran_alloc(npages); +#else + alloc = (uintptr_t)gran_alloc(g_physhandle, npages); +#endif + if (!alloc) + { + sdbg("ERROR: Failed to allocate %d pages\n", npages); + ret = -ENOMEM; + goto errout_with_cbr; + } + + /* Save the information in the CBR structure. Note that alloc is in + * 4KB pages, already in the right form for the CBR. + */ + + DEBUGASSERT(alloc <= 0xff); + + cbr->cbr = alloc; + cbr->pages = npages; + tcb->xcp.cbr = cbr; + + irqrestore(flags); + return OK; + +errout_with_cbr: + z180_mmu_freecbr(cbr); + +errout_with_irq: + irqrestore(flags); + return ret; +} + +/**************************************************************************** + * Name: up_addrenv_clone + * + * Description: + * This function is called from the core scheduler logic when a thread + * is created that needs to share the address ennvironment of its parent + * task. In this case, the parent's address environment needs to be + * "cloned" for the child. + * + * Input Parameters: + * ptcb - The TCB of the parent task that has the address environment. + * ctcb - The TCB of the child thread needing the address environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ADDRENV +int up_addrenv_clone(FAR const _TCB *ptcb, FAR _TCB *ctcb) +{ + irqstate_t flags; + + /* Make sure that the child has no address environment. It is okay if + * if the parent does not have one. + */ + + DEBUGASSERT(ctcb->xcp.cbr == NULL); + + flags = irqsave(); + if (ptcb->xcp.cbr) + { + /* Clone the CBR by incrementing the reference counting and saving a + * copy in the child thread's TCB. + */ + + ptcb->xcp.cbr.crefs++; + ctcb->xcp.cbr = ptcb->xcp.cbr; + } + + irqrestore(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: up_addrenv_instantiate + * + * Description: + * After an address environment has been established for a task (via + * up_addrenv_create(). This function may be called to to instantiate + * that address environment in the virtual address space. this might be + * necessary, for example, to load the code for the task from a file or + * to access address environment private data. + * + * Input Parameters: + * tcb - The TCB of the task or thread whose the address environment will + * be instantiated. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ADDRENV +int up_addrenv_instantiate(FAR _TCB *tcb) +{ + irqstate_t flags; + + /* Check if the task has an address environment. */ + + flags = irqsave(); + if (tcb->xcp.cbr) + { + /* Yes... write the CBR value into CBR register */ + + outp(Z180_MMU_CBR, tcb->xcp.cbr.cbr); + /* Clone the CBR by incrementing the reference counting and saving a + * copy in the child thread's TCB. + */ + + ptcb->xcp.cbr.crefs++; + ctcb->xcp.cbr = ptcb->xcp.cbr; + } + + irqrestore(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: up_addrenv_release + * + * Description: + * This function is called when a task or thread exits in order to release + * its reference to an address environment. When there are no further + * references to an address environment, that address environment should + * be destroyed. + * + * Input Parameters: + * tcb - The TCB of the task or thread whose the address environment will + * be released. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ADDRENV +int up_addrenv_release(FAR _TCB *tcb) +{ + FAR struct z180_cbr_s *cbr; + irqstate_t flags; + + /* Check if the task has an address environment. */ + + flags = irqsave(); + cbr = tcb->xcp.cbr; + if (cbr) + { + /* Nullify the reference to the CBR structgure and decrement the number + * of references on the CBR. + */ + + tcb->xcp.cbr = NULL; + + /* If the reference count would decrement to zero, then free the CBR + * structure. + */ + + if (cbr->crefs <= 1) + { + z180_mmu_freecbr(cbr); + } + else + { + /* Otherwise, just decrement the reference count */ + + cbr->crefs--; + } + } + + irqrestore(flags); + return OK; +} +#endif + diff --git a/nuttx/arch/z80/src/z180/z180_mmu.h b/nuttx/arch/z80/src/z180/z180_mmu.h new file mode 100644 index 000000000..1a4c03406 --- /dev/null +++ b/nuttx/arch/z80/src/z180/z180_mmu.h @@ -0,0 +1,149 @@ +/**************************************************************************** + * arch/z80/src/z180/z180_mmu.h + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_Z80_SRC_Z180_Z180_MMU_H +#define __ARCH_Z80_SRC_Z180_Z180_MMU_H + +/* See arch/z80/src/z180/z180_mmu.txt for additional information */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "z180_iomap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Virtual addresses */ + +#ifndef CONFIG_Z180_BANKAREA_VIRTBASE +# warning "Assuming Bank Area at virtual address 0x8000" +# define CONFIG_Z180_BANKAREA_VIRTBASE 0x8000 +#endif + +#ifndef CONFIG_Z180_COMMON1AREA_VIRTBASE +# warning "Assuming Common Area 1 at virtual address 0xc000" +# define CONFIG_Z180_COMMON1AREA_VIRTBASE 0xc000 +#endif + +#if CONFIG_Z180_BANKAREA_VIRTBASE > CONFIG_Z180_COMMON1AREA_VIRTBASE +# error "CONFIG_Z180_BANKAREA_VIRTBASE > CONFIG_Z180_COMMON1AREA_VIRTBASE" +#endif + +/* Physical addresses */ + +#ifndef CONFIG_Z180_BANKAREA_PHYSBASE +# warning "Assuming Bank Area 1 at physical address 0x080000" +# define CONFIG_Z180_BANKAREA_PHYSBASE 0x08000 +#endif + +#ifndef CONFIG_Z180_PHYSHEAP_START +# warning "Assuming physical heap starts at physical address 0x0c000" +# define CONFIG_Z180_PHYSHEAP_START 0x0c000 +#endif + +#ifndef CONFIG_Z180_PHYSHEAP_END +# warning "Assuming physical heap ends at physical address 0x100000" +# define CONFIG_Z180_PHYSHEAP_END 0x100000 +#endif + +#if CONFIG_Z180_BANKAREA_PHYSBASE > CONFIG_Z180_PHYSHEAP_START +# error "CONFIG_Z180_BANKAREA_PHYSBASE > CONFIG_Z180_PHYSHEAP_START" +#endif + +#if CONFIG_Z180_PHYSHEAP_START > CONFIG_Z180_PHYSHEAP_END +# error "CONFIG_Z180_PHYSHEAP_START > CONFIG_Z180_PHYSHEAP_END" +#endif + +/* Each page is 4KB */ + +#define Z180_PAGESHIFT (12) +#define Z180_PAGESIZE (1 << Z180_PAGESHIFT) +#define Z180_PAGEMASK (Z180_PAGESIZE - 1) +#define PHYS_ALIGN(phys) ((phys) >> Z180_PAGESHIFT) +#define PHYS_ALIGNUP(phys) (((phys) + Z180_PAGEMASK) >> Z180_PAGESHIFT) + +/* Physical pages */ + +#define Z180_BANKAREA_PHYSPAGE PHYS_ALIGN(CONFIG_Z180_BANKAREA_PHYSBASE) +#define Z180_PHYSHEAP_STARTPAGE PHYS_ALIGN(CONFIG_Z180_PHYSHEAP_START) +#define Z180_PHYSHEAP_ENDPAGE PHYS_ALIGN(CONFIG_Z180_PHYSHEAP_END) +#define Z180_PHYSHEAP_NPAGES (Z180_PHYSHEAP_ENDPAGE - Z180_PHYSHEAP_STARTPAGE + 1) + +/* MMU register values */ + +#define Z180_CBAR_VALUE \ + ((((CONFIG_Z180_BANKAREA_VIRTBASE >> 12) & 0x0f) << CBAR_BA_SHIFT) \ + (((CONFIG_Z180_COMMON1AREA_VIRTBASE >> 12) & 0x0f) << CBAR_CA_SHIFT)) + +#define Z180_BBR_VALUE \ + ((CONFIG_Z180_BANKAREA_PHYSBASE >> 12) & 0xff) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: z180_mmu_lowinit + * + * Description: + * Low-level, power-up initialization of the z180 MMU. this must be + * called very early in the boot process to get the basic operating + * memory configuration correct. This function does *not* perform all + * necessray MMU initialization... only the basics needed at power-up. + * z180_mmu_init() must be called later to complete the entire MMU + * initialization. + * + ****************************************************************************/ + +void z180_mmu_lowinit(void) __naked; + +/**************************************************************************** + * Name: z180_mmu_init + * + * Description: + * Perform higher level initializatin of the MMU and physical memory + * memory management logic. + * + ****************************************************************************/ + +void z180_mmu_init(void); + +#endif /* __ARCH_Z80_SRC_Z180_Z180_MMU_H */ diff --git a/nuttx/arch/z80/src/z180/z180_mmu.txt b/nuttx/arch/z80/src/z180/z180_mmu.txt new file mode 100644 index 000000000..e12f41e9b --- /dev/null +++ b/nuttx/arch/z80/src/z180/z180_mmu.txt @@ -0,0 +1,114 @@ +The MMU translates every memory address from 16 to 20 bits. The MMU uses +three internal control registers. On reset the MMU gives a straight logical +to physical mapping, simulating the Z80 and, of course, limiting the address +space to 64k. + +Logical Address Spaces +====================== + +The 64KB CPU logical address space is interpreted by the MMU as consisting +of up to three separate logical address areas: + + Common Area 0, + Bank Area, and + Common Area 1. + +Common 0, if it exists, always starts at logical address 0000 and runs up +to the Bank Area. The Bank Area then runs to the start of Common Area 1. + +Registers +========= + +CBAR (Comman/Bank Area Register) + + CBAR is an 8 bit I/O port that can be accessed by the processor's OUT and + IN instructions. The lower 4-bits of CBAR (BA) specify the starting logical + address of the Bank Area, and the upper 4-bits (CA) give the start of + Common Area 1. These bits determine the upper four bits of the 16-bit + address. If CBAR were 0xa8, then the Base Area starts at logical address + 0x8000 and Common Area 1 starts at logical address 0xa000. This gives a + mapping granualarity of 4Kb in the logical address space. + + The CA and BA fields of CBAR may be freely programmed subject only to the + restriction that CA may never be less than BA. + +BBAR (Base Area Bank Register) + + BBR specifies the starting physical address of the base area (the logical + start address is in CBAR). + +CBR (Common Bank Register) + + CBR provides the same information for Common Area 1. + +Both the BBAR and the CBR specify the upper 8-bits of the 20-bit physical +address in the mapping. Hence, mapping is performed with a granularity of +4Kb in the physical address space. + +Physical to Logical Address Mapping +=================================== + +A simple formula gives the translation from logical to physical address for +the Bank Area: + + Physical = Logical + (BBR * 4096) + +The same formula gives Common Area 1: + + Physical = Logical + (CBR * 4096) + +Reset Configuration +=================== + +On reset, the CBAR is set to 0xf0, and CBR and BBR are set to 0x00. This +maps logical to physical with no translation; the Bank Area starts at +logical address 0x0000 and Common 1 at 0xf000. The Bank Area starts at +phsycial address 0x00000 (BBR=0), as does Common Area 1 (CBR=0). If the +logical address is 0x1000, then the MMU allocates this to the Bank Area +and adds the physical base of bank to it (0x00000), giving a translated +address of 0x01000. Similarly, logical 0xf800 is in Common Area 1, and +translates to 0x0f800. + +Configurations +============== + +You can divide the logical address space into one, two, or three areas. + +1) Three areas: + + CBAR:CA > CBAR:BA > 0x0000 + +2a) Two areas (Bank Area and Common Area 1): + + CBAR:CA > CBAR:BA = 0x0000 + +2a) Two areas (Common Area 0 and Common Area 1): + + CBAR:CA = CBAR:BA > 0x0000 + +3) One area (Common Area 1): + + CBAR:CA = CBAR:BA = 0x0000 + +NuttX Memory Organization +========================= + +Common Area 0: This area holds the common NuttX code that is directly +call-able from all application threads. Common Area always starts at +logical address 0x0000 and extends to the Bank Area + +Base Area: This area holds the common NuttX data (including the share- +able heap) that is accessible from all applications and extends to +Common Area 1. + +NOTE: That is execution from RAM, the common NuttX code and data may +be contiguous and lie in the same areas (either Common Area 0 or the +Bank Area). The two areas above would apply in a ROM'ed system, where +Common Area 1 is ROM and the Base Area is RAM. + +Common Area 1: This area holds the code and data that is unique to +a particular task. This area extends to the end of the logical address +space. All tasks share the same logical Common Area 2 logical address +(in the CBAR), but each has a unique mapping to different, underlying +physical addresses. Each task will then have its own, unique CBR value +that must be restored with each context switch to the task. diff --git a/nuttx/binfmt/Kconfig b/nuttx/binfmt/Kconfig index ae02c276a..cbf909327 100644 --- a/nuttx/binfmt/Kconfig +++ b/nuttx/binfmt/Kconfig @@ -15,6 +15,7 @@ if !BINFMT_DISABLE config NXFLAT bool "Enable the NXFLAT Binary Format" default n + select PIC ---help--- Enable support for the NXFLAT binary format. Default: n @@ -34,6 +35,10 @@ endif endif +config PIC + bool + default n + config BINFMT_CONSTRUCTORS bool "C++ Static Constructor Support" default n diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt index b4700433b..23f5e4380 100644 --- a/nuttx/configs/README.txt +++ b/nuttx/configs/README.txt @@ -160,6 +160,9 @@ defconfig -- This is a configuration file similar to the Linux CONFIG_ARCH_IRQPRIO Define if the architecture suports prioritizaton of interrupts and the up_prioritize_irq() API. + CONFIG_ADDRENV + The CPU supports an MMU and CPU port supports provision of address + environments for tasks (making the, perhaps, processes). Some architectures require a description of the RAM configuration: diff --git a/nuttx/configs/pic32-starterkit/src/up_spi.c b/nuttx/configs/pic32-starterkit/src/up_spi.c index 52d46af89..42e7c4b9c 100644 --- a/nuttx/configs/pic32-starterkit/src/up_spi.c +++ b/nuttx/configs/pic32-starterkit/src/up_spi.c @@ -154,7 +154,7 @@ int pic32mx_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cm #endif #endif -#ifdef CONFIG_PIC31MX_SPI1 +#ifdef CONFIG_PIC32MX_SPI1 void pic31mx_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { sspdbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); @@ -176,7 +176,7 @@ int pic31mx_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cm #endif #endif -#ifdef CONFIG_PIC31MX_SPI3 +#ifdef CONFIG_PIC32MX_SPI3 void pic32mx_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { sspdbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); diff --git a/nuttx/configs/pic32mx7mmb/src/up_spi.c b/nuttx/configs/pic32mx7mmb/src/up_spi.c index a15881868..add2b2d65 100644 --- a/nuttx/configs/pic32mx7mmb/src/up_spi.c +++ b/nuttx/configs/pic32mx7mmb/src/up_spi.c @@ -192,7 +192,7 @@ int pic32mx_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cm #endif #endif -#ifdef CONFIG_PIC31MX_SPI2 +#ifdef CONFIG_PIC32MX_SPI2 void pic31mx_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); @@ -215,7 +215,7 @@ int pic31mx_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cm #endif #endif -#ifdef CONFIG_PIC31MX_SPI3 +#ifdef CONFIG_PIC32MX_SPI3 void pic32mx_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); diff --git a/nuttx/include/nuttx/arch.h b/nuttx/include/nuttx/arch.h index c836a7557..54c234d8d 100644 --- a/nuttx/include/nuttx/arch.h +++ b/nuttx/include/nuttx/arch.h @@ -67,10 +67,8 @@ typedef CODE void (*sig_deliver_t)(FAR _TCB *tcb); ****************************************************************************/ #ifdef __cplusplus -#define EXTERN extern "C" -extern "C" { -#else -#define EXTERN extern +extern "C" +{ #endif /**************************************************************************** @@ -98,7 +96,7 @@ extern "C" { * ****************************************************************************/ -EXTERN void up_initialize(void); +void up_initialize(void); /**************************************************************************** * Name: up_idle @@ -114,7 +112,7 @@ EXTERN void up_initialize(void); * ****************************************************************************/ -EXTERN void up_idle(void); +void up_idle(void); /**************************************************************************** * Name: up_initial_state @@ -130,7 +128,7 @@ EXTERN void up_idle(void); * ****************************************************************************/ -EXTERN void up_initial_state(FAR _TCB *tcb); +void up_initial_state(FAR _TCB *tcb); /**************************************************************************** * Name: up_create_stack @@ -155,7 +153,7 @@ EXTERN void up_initial_state(FAR _TCB *tcb); ****************************************************************************/ #ifndef CONFIG_CUSTOM_STACK -EXTERN int up_create_stack(FAR _TCB *tcb, size_t stack_size); +int up_create_stack(FAR _TCB *tcb, size_t stack_size); #endif /**************************************************************************** @@ -180,7 +178,7 @@ EXTERN int up_create_stack(FAR _TCB *tcb, size_t stack_size); ****************************************************************************/ #ifndef CONFIG_CUSTOM_STACK -EXTERN int up_use_stack(FAR _TCB *tcb, FAR void *stack, size_t stack_size); +int up_use_stack(FAR _TCB *tcb, FAR void *stack, size_t stack_size); #endif /**************************************************************************** @@ -193,7 +191,7 @@ EXTERN int up_use_stack(FAR _TCB *tcb, FAR void *stack, size_t stack_size); ****************************************************************************/ #ifndef CONFIG_CUSTOM_STACK -EXTERN void up_release_stack(FAR _TCB *dtcb); +void up_release_stack(FAR _TCB *dtcb); #endif /**************************************************************************** @@ -216,7 +214,7 @@ EXTERN void up_release_stack(FAR _TCB *dtcb); * ****************************************************************************/ -EXTERN void up_unblock_task(FAR _TCB *tcb); +void up_unblock_task(FAR _TCB *tcb); /**************************************************************************** * Name: up_block_task @@ -242,7 +240,7 @@ EXTERN void up_unblock_task(FAR _TCB *tcb); * ****************************************************************************/ -EXTERN void up_block_task(FAR _TCB *tcb, tstate_t task_state); +void up_block_task(FAR _TCB *tcb, tstate_t task_state); /**************************************************************************** * Name: up_release_pending @@ -261,7 +259,7 @@ EXTERN void up_block_task(FAR _TCB *tcb, tstate_t task_state); * ****************************************************************************/ -EXTERN void up_release_pending(void); +void up_release_pending(void); /**************************************************************************** * Name: up_reprioritize_rtr @@ -287,7 +285,7 @@ EXTERN void up_release_pending(void); * ****************************************************************************/ -EXTERN void up_reprioritize_rtr(FAR _TCB *tcb, uint8_t priority); +void up_reprioritize_rtr(FAR _TCB *tcb, uint8_t priority); /**************************************************************************** * Name: _exit @@ -349,7 +347,7 @@ EXTERN void up_reprioritize_rtr(FAR _TCB *tcb, uint8_t priority); ****************************************************************************/ #ifndef CONFIG_DISABLE_SIGNALS -EXTERN void up_schedule_sigaction(FAR _TCB *tcb, sig_deliver_t sigdeliver); +void up_schedule_sigaction(FAR _TCB *tcb, sig_deliver_t sigdeliver); #endif /**************************************************************************** @@ -363,7 +361,7 @@ EXTERN void up_schedule_sigaction(FAR _TCB *tcb, sig_deliver_t sigdeliver); ****************************************************************************/ #ifndef CONFIG_HEAP_BASE -EXTERN void up_allocate_heap(FAR void **heap_start, size_t *heap_size); +void up_allocate_heap(FAR void **heap_start, size_t *heap_size); #endif /**************************************************************************** @@ -382,6 +380,95 @@ EXTERN void up_allocate_heap(FAR void **heap_start, size_t *heap_size); # define up_getpicbase(ppicbase) #endif +/**************************************************************************** + * Name: up_addrenv_create + * + * Description: + * This function is called from the binary loader logic when a new + * task is created in RAM in order to instantiate an address environment for + * the task. + * + * Input Parameters: + * tcb - The TCB of the task needing the address environment. + * envsize - The size (in bytes) of the address environment needed by the + * task. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ADDRENV +int up_addrenv_create(FAR _TCB *tcb, size_t envsize); +#endif + +/**************************************************************************** + * Name: up_addrenv_clone + * + * Description: + * This function is called from the core scheduler logic when a thread + * is created that needs to share the address ennvironment of its parent + * task. In this case, the parent's address environment needs to be + * "cloned" for the child. + * + * Input Parameters: + * ptcb - The TCB of the parent task that has the address environment. + * ctcb - The TCB of the child thread needing the address environment. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ADDRENV +int up_addrenv_clone(FAR const _TCB *ptcb, FAR _TCB *ctcb); +#endif + +/**************************************************************************** + * Name: up_addrenv_instantiate + * + * Description: + * After an address environment has been established for a task (via + * up_addrenv_create(). This function may be called to to instantiate + * that address environment in the virtual address space. this might be + * necessary, for example, to load the code for the task from a file or + * to access address environment private data. + * + * Input Parameters: + * tcb - The TCB of the task or thread whose the address environment will + * be instantiated. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ADDRENV +int up_addrenv_instantiate(FAR _TCB *tcb); +#endif + +/**************************************************************************** + * Name: up_addrenv_release + * + * Description: + * This function is called when a task or thread exits in order to release + * its reference to an address environment. When there are no further + * references to an address environment, that address environment should + * be destroyed. + * + * Input Parameters: + * tcb - The TCB of the task or thread whose the address environment will + * be released. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ADDRENV +int up_addrenv_release(FAR _TCB *tcb); +#endif + /**************************************************************************** * Name: up_interrupt_context * @@ -391,7 +478,7 @@ EXTERN void up_allocate_heap(FAR void **heap_start, size_t *heap_size); * ****************************************************************************/ -EXTERN bool up_interrupt_context(void); +bool up_interrupt_context(void); /**************************************************************************** * Name: up_enable_irq @@ -413,7 +500,7 @@ EXTERN bool up_interrupt_context(void); ****************************************************************************/ #ifndef CONFIG_ARCH_NOINTC -EXTERN void up_enable_irq(int irq); +void up_enable_irq(int irq); #endif /**************************************************************************** @@ -431,7 +518,7 @@ EXTERN void up_enable_irq(int irq); ****************************************************************************/ #ifndef CONFIG_ARCH_NOINTC -EXTERN void up_disable_irq(int irq); +void up_disable_irq(int irq); #endif /**************************************************************************** @@ -446,7 +533,7 @@ EXTERN void up_disable_irq(int irq); ****************************************************************************/ #ifdef CONFIG_ARCH_IRQPRIO -EXTERN int up_prioritize_irq(int irq, int priority); +int up_prioritize_irq(int irq, int priority); #endif /**************************************************************************** @@ -483,7 +570,7 @@ EXTERN int up_prioritize_irq(int irq, int priority); ****************************************************************************/ #ifdef CONFIG_ARCH_ROMGETC -EXTERN char up_romgetc(FAR const char *ptr); +char up_romgetc(FAR const char *ptr); #else # define up_romgetc(ptr) (*ptr) #endif @@ -497,8 +584,8 @@ EXTERN char up_romgetc(FAR const char *ptr); * ***************************************************************************/ -EXTERN void up_mdelay(unsigned int milliseconds); -EXTERN void up_udelay(useconds_t microseconds); +void up_mdelay(unsigned int milliseconds); +void up_udelay(useconds_t microseconds); /**************************************************************************** * Name: up_cxxinitialize @@ -517,7 +604,7 @@ EXTERN void up_udelay(useconds_t microseconds); ***************************************************************************/ #if defined(CONFIG_HAVE_CXX) && defined(CONFIG_HAVE_CXXINITIALIZE) -EXTERN void up_cxxinitialize(void); +void up_cxxinitialize(void); #endif /**************************************************************************** @@ -537,7 +624,7 @@ EXTERN void up_cxxinitialize(void); * ****************************************************************************/ -EXTERN void sched_process_timer(void); +void sched_process_timer(void); /**************************************************************************** * Name: irq_dispatch @@ -549,7 +636,7 @@ EXTERN void sched_process_timer(void); * ***************************************************************************/ -EXTERN void irq_dispatch(int irq, FAR void *context); +void irq_dispatch(int irq, FAR void *context); /**************************************************************************** * Board-specific button interfaces exported by the board-specific logic @@ -571,7 +658,7 @@ EXTERN void irq_dispatch(int irq, FAR void *context); ****************************************************************************/ #ifdef CONFIG_ARCH_BUTTONS -EXTERN void up_buttoninit(void); +void up_buttoninit(void); #endif /**************************************************************************** @@ -592,7 +679,7 @@ EXTERN void up_buttoninit(void); ****************************************************************************/ #ifdef CONFIG_ARCH_BUTTONS -EXTERN uint8_t up_buttons(void); +uint8_t up_buttons(void); #endif /**************************************************************************** @@ -613,7 +700,7 @@ EXTERN uint8_t up_buttons(void); ****************************************************************************/ #ifdef CONFIG_ARCH_IRQBUTTONS -EXTERN xcpt_t up_irqbutton(int id, xcpt_t irqhandler); +xcpt_t up_irqbutton(int id, xcpt_t irqhandler); #endif /************************************************************************************ @@ -625,17 +712,17 @@ EXTERN xcpt_t up_irqbutton(int id, xcpt_t irqhandler); ************************************************************************************/ #ifdef CONFIG_ARCH_RELAYS -EXTERN void up_relaysinit(void); -EXTERN void relays_setstat(int relays, bool stat); -EXTERN bool relays_getstat(int relays); -EXTERN void relays_setstats(uint32_t relays_stat); -EXTERN uint32_t relays_getstats(void); -EXTERN void relays_onoff(int relays, uint32_t mdelay); -EXTERN void relays_onoffs(uint32_t relays_stat, uint32_t mdelay); -EXTERN void relays_resetmode(int relays); -EXTERN void relays_powermode(int relays); -EXTERN void relays_resetmodes(uint32_t relays_stat); -EXTERN void relays_powermodes(uint32_t relays_stat); +void up_relaysinit(void); +void relays_setstat(int relays, bool stat); +bool relays_getstat(int relays); +void relays_setstats(uint32_t relays_stat); +uint32_t relays_getstats(void); +void relays_onoff(int relays, uint32_t mdelay); +void relays_onoffs(uint32_t relays_stat, uint32_t mdelay); +void relays_resetmode(int relays); +void relays_powermode(int relays); +void relays_resetmodes(uint32_t relays_stat); +void relays_powermodes(uint32_t relays_stat); #endif /**************************************************************************** @@ -650,9 +737,8 @@ EXTERN void relays_powermodes(uint32_t relays_stat); * ****************************************************************************/ -EXTERN int up_putc(int ch); +int up_putc(int ch); -#undef EXTERN #ifdef __cplusplus } #endif diff --git a/nuttx/mm/mm_graninit.c b/nuttx/mm/mm_graninit.c index e43839ad6..54b729988 100644 --- a/nuttx/mm/mm_graninit.c +++ b/nuttx/mm/mm_graninit.c @@ -74,7 +74,6 @@ FAR struct gran_s *g_graninfo; * Perfrom common GRAN initialization. * * Input Parameters: - * info - Private granule data structure pointer * heapstart - Start of the granule allocation heap * heapsize - Size of heap in bytes * log2gran - Log base 2 of the size of one granule. 0->1 byte, diff --git a/nuttx/sched/Kconfig b/nuttx/sched/Kconfig index ab0de5b47..afb35c1c0 100644 --- a/nuttx/sched/Kconfig +++ b/nuttx/sched/Kconfig @@ -40,7 +40,7 @@ config JULIAN_TIME config START_YEAR int "start year" - default 2010 + default 2013 config START_MONTH int "start month" @@ -384,14 +384,6 @@ config PREALLOC_TIMERS comment "Stack and heap information" -config CUSTOM_STACK - bool "Enable custom stack" - default n - ---help--- - The up_ implementation will handle all stack operations outside of the - nuttx model. This is necessary for certain architectures that have - have hardware stacks (such as the 8051 family). - config IDLETHREAD_STACKSIZE int "Idle thread stack size" default 1024 -- cgit v1.2.3