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
This commit is contained in:
patacongo 2012-12-11 18:04:04 +00:00
parent ac24179c23
commit 07827c3c61
9 changed files with 904 additions and 50 deletions

View File

@ -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

View File

@ -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"

View File

@ -86,6 +86,21 @@
#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];

View File

@ -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

View File

@ -42,14 +42,13 @@ 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_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

View File

@ -62,6 +62,7 @@
.globl _os_start ; OS entry point
.globl _up_doirq ; Interrupt decoding logic
.globl z180_mmu_lowinit ; MMU initialization logic
;**************************************************************************
; Reset entry point
@ -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

View File

@ -0,0 +1,405 @@
/****************************************************************************
* arch/z80/src/z180/z180_mmu.c
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#include <nuttx/gram.h>
#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

View File

@ -0,0 +1,149 @@
/****************************************************************************
* arch/z80/src/z180/z180_mmu.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#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 */

View File

@ -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.