lm32: Remove obsolete architecture

Updates rtems/rtos/rtems#5025
This commit is contained in:
Joel Sherrill
2024-12-19 16:22:29 -06:00
committed by Kinsey Moore
parent 82624328da
commit 740f736f9e
88 changed files with 0 additions and 10344 deletions

View File

@@ -1,56 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSImplClassicIntr
*
* @brief BSP interrupt support for LM32.
*/
/*
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
*
* Copyright (C) 2008, 2009 embedded brains GmbH & Co. KG
*
* 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.
*
* 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 LIBBSP_LM32_IRQ_CONFIG_H
#define LIBBSP_LM32_IRQ_CONFIG_H
#include <stdint.h>
/**
* @addtogroup RTEMSImplClassicIntr
*
* @{
*/
/**
* @brief Maximum vector number.
*/
#define BSP_INTERRUPT_VECTOR_COUNT 32
/** @} */
#endif /* LIBBSP_LM32_IRQ_CONFIG_H */

View File

@@ -1,76 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_ac97 RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist AC97 driver
*/
/* milkymist_ac97.h
*
* Milkymist AC97 driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_ac97 Milkymist AC97
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist AC97 driver
* @{
*/
#ifndef __MILKYMIST_AC97_H_
#define __MILKYMIST_AC97_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Ioctls. 0x41 is 'A' */
#define SOUND_MIXER_MIC 0x0
#define SOUND_MIXER_LINE 0x1
#define SOUND_MIXER_READ(x) (0x4100+x)
#define SOUND_MIXER_WRITE(x) (0x4110+x)
#define SOUND_SND_SUBMIT_PLAY 0x4120
#define SOUND_SND_COLLECT_PLAY 0x4121
#define SOUND_SND_SUBMIT_RECORD 0x4122
#define SOUND_SND_COLLECT_RECORD 0x4123
struct snd_buffer {
unsigned int nsamples;
void *user;
unsigned int samples[];
};
rtems_device_driver ac97_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver ac97_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver ac97_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define AC97_DRIVER_TABLE_ENTRY {ac97_initialize, \
ac97_open, NULL, NULL, NULL, ac97_control}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_AC97_H_ */

View File

@@ -1,59 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_buttons RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist buttons driver
*/
/* milkymist_buttons.h
*
* Milkymist buttons driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2011 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_buttons Milkymist buttons
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist buttons driver
* @{
*/
#ifndef __MILKYMIST_BUTTONS_H_
#define __MILKYMIST_BUTTONS_H_
#ifdef __cplusplus
extern "C" {
#endif
rtems_device_driver buttons_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver buttons_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver buttons_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define BUTTONS_DRIVER_TABLE_ENTRY { buttons_initialize, \
buttons_open, NULL, buttons_read, NULL, NULL}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_BUTTONS_H_ */

View File

@@ -1,68 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_dmx RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist DMX512 driver
*/
/* milkymist_dmx.h
*
* Milkymist DMX512 driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_dmx Milkymist DMX512
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist DMX512 driver
* @{
*/
#ifndef __MILKYMIST_DMX_H_
#define __MILKYMIST_DMX_H_
#ifdef __cplusplus
extern "C" {
#endif
#define DMX_SET_THRU 0x4400
#define DMX_GET_THRU 0x4401
rtems_device_driver dmx_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver dmx_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver dmx_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver dmx_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define DMX_DRIVER_TABLE_ENTRY {dmx_initialize, \
NULL, NULL, dmx_read, dmx_write, dmx_control}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_DMX_H_ */

View File

@@ -1,64 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_flash RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist Flash
*/
/* milkymist_flash.h
*
* Copyright (C) 2010 Sebastien Bourdeauducq
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
*/
/**
* @defgroup lm32_milkymist_flash Milkymist Flash
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist Flash
* @{
*/
#ifndef __MILKYMIST_FLASH_H_
#define __MILKYMIST_FLASH_H_
/* Ioctls */
#define FLASH_GET_SIZE 0x4600
#define FLASH_GET_BLOCKSIZE 0x4601
#define FLASH_ERASE_BLOCK 0x4602
struct flash_partition {
unsigned int start_address;
unsigned int length;
};
rtems_device_driver flash_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver flash_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver flash_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver flash_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define FLASH_DRIVER_TABLE_ENTRY {flash_initialize, \
NULL, NULL, flash_read, flash_write, flash_control}
#endif /* __MILKYMIST_FLASH_H_ */

View File

@@ -1,59 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_gpio RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist GPIO driver
*/
/* milkymist_gpio.h
*
* Milkymist GPIO driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_gpio Milkymist GPIO
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist GPIO driver
* @{
*/
#ifndef __MILKYMIST_GPIO_H_
#define __MILKYMIST_GPIO_H_
#ifdef __cplusplus
extern "C" {
#endif
rtems_device_driver gpio_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver gpio_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver gpio_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define GPIO_DRIVER_TABLE_ENTRY { gpio_initialize, \
NULL, NULL, gpio_read, gpio_write, NULL}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_GPIO_H_ */

View File

@@ -1,59 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_ir RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist RC5 IR driver
*/
/* milkymist_ir.h
*
* Milkymist RC5 IR driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_ir Milkymist IR
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist RC5 IR driver
* @{
*/
#ifndef __MILKYMIST_IR_H_
#define __MILKYMIST_IR_H_
#ifdef __cplusplus
extern "C" {
#endif
rtems_device_driver ir_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver ir_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver ir_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define IR_DRIVER_TABLE_ENTRY {ir_initialize, \
ir_open, NULL, ir_read, NULL, NULL}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_IR_H_ */

View File

@@ -1,32 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_memcard RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist memory card driver
*/
/* milkymist_memcard.h
*
* Milkymist memory card driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_memcard Milkymist memory card
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist memory card driver
* @{
*/
#ifndef __MILKYMIST_MEMCARD_H_
#define __MILKYMIST_MEMCARD_H_
rtems_status_code memcard_register(void);
#endif /* __MILKYMIST_MEMCARD_H_ */
/** @} */

View File

@@ -1,59 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_midi RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist MIDI driver
*/
/* milkymist_midi.h
*
* Milkymist MIDI driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_midi Milkymist MIDI
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist MIDI driver
* @{
*/
#ifndef __MILKYMIST_MIDI_H_
#define __MILKYMIST_MIDI_H_
#ifdef __cplusplus
extern "C" {
#endif
rtems_device_driver midi_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver midi_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver midi_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define MIDI_DRIVER_TABLE_ENTRY {midi_initialize, \
midi_open, NULL, midi_read, NULL, NULL}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_MIDI_H_ */

View File

@@ -1,72 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_pfpu RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist PFPU driver
*/
/* milkymist_pfpu.h
*
* Milkymist PFPU driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_pfpu Milkymist PFPU
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist PFPU driver
* @{
*/
#ifndef __MILKYMIST_PFPU_H_
#define __MILKYMIST_PFPU_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Ioctls */
#define PFPU_EXECUTE 0x4600
#define PFPU_PROGSIZE (2048)
#define PFPU_REG_COUNT (128)
struct pfpu_td {
unsigned int *output;
unsigned int hmeshlast;
unsigned int vmeshlast;
unsigned int *program;
unsigned int progsize;
float *registers;
/** @brief shall we update the "registers" array after completion */
bool update;
/** @brief shall we invalidate L1 data cache after completion */
bool invalidate;
};
rtems_device_driver pfpu_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver pfpu_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define PFPU_DRIVER_TABLE_ENTRY {pfpu_initialize, \
NULL, NULL, NULL, NULL, pfpu_control}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_PFPU_H_ */

View File

@@ -1,98 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_tmu RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist TMU driver
*/
/* milkymist_tmu.h
*
* Milkymist TMU driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_tmu Milkymist TMU
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist TMU driver
* @{
*/
#ifndef __MILKYMIST_TMU_H_
#define __MILKYMIST_TMU_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Ioctls */
#define TMU_EXECUTE 0x5400
#define TMU_EXECUTE_NONBLOCK 0x5401
#define TMU_EXECUTE_WAIT 0x5402
struct tmu_vertex {
int x;
int y;
} __attribute__((packed));
struct tmu_td {
unsigned int flags;
unsigned int hmeshlast;
unsigned int vmeshlast;
unsigned int brightness;
unsigned short chromakey;
struct tmu_vertex *vertices;
unsigned short *texfbuf;
unsigned int texhres;
unsigned int texvres;
unsigned int texhmask;
unsigned int texvmask;
unsigned short *dstfbuf;
unsigned int dsthres;
unsigned int dstvres;
int dsthoffset;
int dstvoffset;
unsigned int dstsquarew;
unsigned int dstsquareh;
unsigned int alpha;
bool invalidate_before;
bool invalidate_after;
};
#define TMU_BRIGHTNESS_MAX (63)
#define TMU_MASK_NOFILTER (0x3ffc0)
#define TMU_MASK_FULL (0x3ffff)
#define TMU_FIXEDPOINT_SHIFT (6)
#define TMU_ALPHA_MAX (63)
#define TMU_MESH_MAXSIZE (128)
#define TMU_FLAG_CHROMAKEY (2)
#define TMU_FLAG_ADDITIVE (4)
rtems_device_driver tmu_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver tmu_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define TMU_DRIVER_TABLE_ENTRY {tmu_initialize, \
NULL, NULL, NULL, NULL, tmu_control}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_TMU_H_ */

View File

@@ -1,71 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_usbinput RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist USB input devices driver
*/
/* milkymist_usbinput.h
*
* Milkymist USB input devices driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2012 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_usbinput Milkymist USB input devices
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist USB input devices driver
* @{
*/
#ifndef __MILKYMIST_USBINPUT_H_
#define __MILKYMIST_USBINPUT_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Ioctls */
#define USBINPUT_LOAD_FIRMWARE 0x5500
struct usbinput_firmware_description {
const unsigned char *data;
int length;
};
rtems_device_driver usbinput_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver usbinput_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver usbinput_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver usbinput_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define USBINPUT_DRIVER_TABLE_ENTRY {usbinput_initialize, \
usbinput_open, NULL, usbinput_read, NULL, usbinput_control}
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_USBINPUT_H_ */

View File

@@ -1,53 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_versions RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist versioning driver
*/
/* milkymist_versions.h
*
* Milkymist versioning driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_versions Milkymist versioning
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist versioning driver
* @{
*/
#ifndef __MILKYMIST_VERSIONS_H_
#define __MILKYMIST_VERSIONS_H_
#ifdef __cplusplus
extern "C" {
#endif
rtems_device_driver versions_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver versions_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define VERSIONS_DRIVER_TABLE_ENTRY {versions_initialize, \
NULL, NULL, versions_read, NULL, NULL}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_VERSIONS_H_ */

View File

@@ -1,90 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_video RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist video input driver
*/
/* milkymist_video.h
*
* Milkymist video input driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
/**
* @defgroup lm32_milkymist_video Milkymist Video
* @ingroup RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist video input driver
* @{
*/
#ifndef __MILKYMIST_VIDEO_H_
#define __MILKYMIST_VIDEO_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Ioctls */
#define VIDEO_BUFFER_LOCK 0x5600
#define VIDEO_BUFFER_UNLOCK 0x5601
#define VIDEO_SET_BRIGHTNESS 0x5602
#define VIDEO_GET_BRIGHTNESS 0x5603
#define VIDEO_SET_CONTRAST 0x5604
#define VIDEO_GET_CONTRAST 0x5605
#define VIDEO_SET_HUE 0x5606
#define VIDEO_GET_HUE 0x5607
#define VIDEO_GET_SIGNAL 0x5608
#define VIDEO_SET_REGISTER 0x5609
#define VIDEO_GET_REGISTER 0x560a
#define VIDEO_SET_FORMAT 0x560b
enum {
VIDEO_FORMAT_CVBS6 = 0,
VIDEO_FORMAT_CVBS5,
VIDEO_FORMAT_CVBS4,
VIDEO_FORMAT_SVIDEO,
VIDEO_FORMAT_COMPONENT,
};
rtems_device_driver video_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver video_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver video_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
rtems_device_driver video_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
);
#define VIDEO_DRIVER_TABLE_ENTRY {video_initialize, \
video_open, video_close, NULL, NULL, video_control}
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __MILKYMIST_VIDEO_H_ */

View File

@@ -1,59 +0,0 @@
Lattice Mico32
==============
The Lattice Mico32 port uses the system_config.h generated by the Mico
System Builder to retrieve the properties of the peripherals.
Implemented (in shared/ subdirectory)
Polled console driver (uart)
Clock interrupt with 10 ms tick
Networking using Lattice tri-speed ethernet MAC
TODO
----
Support more peripherals:
* uart driver using interrupts
jukka.pietarinen@mrf.fi, 3.12.2008
```
BSP NAME: lm32_evr
BOARD: cRIO-EVR, Micro-Research Finland Oy
BUS: wishbone
CPU FAMILY: lm32 (Lattice Mico32)
CPU: small
COPROCESSORS: none
MODE: 32 bit mode
DEBUG MONITOR: none
```
PERIPHERALS
-----------
```
TIMERS: clock
RESOLUTION: 10 ms
SERIAL PORTS: uart
REAL-TIME CLOCK: none
DMA: none
VIDEO: none
SCSI: none
NETWORKING: tsmac
```
To on the simulator included in lm32-gdb use these commands:
```shell
tar sim --hw-device lm32cpu \
--hw-device "lm32uart/reg 0x80006000 0x100" \
--hw-device "/lm32uart > int int0 /lm32cpu" \
--hw-device "lm32timer/reg 0x80002000 0x80" \
--hw-device "/lm32timer > int int1 /lm32cpu" \
--memory-region 0x08000000,0x4000000
load
```
The simulator is VERY VERY slow when RTEMS is idle.
To speed this up, add SIMULATOR_FAST_IDLE=1 to the
configure command.

View File

@@ -1,29 +0,0 @@
#
# Config file for the lm32_evr BSP
#
# Choices for CPU_MODEL:
# tiny (no cache)
# standard (instruction cache)
# fast (instruction and data cache)
RTEMS_CPU = lm32
include $(RTEMS_ROOT)/make/custom/default.cfg
# This contains the compiler options necessary to select the CPU model
# and (hopefully) optimize for it.
CPU_CFLAGS =
# optimize flag: typically -O2
# ATM, doesn't work with optimization levels > 0
CFLAGS_OPTIMIZE_V = -O0 -g
CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
LDFLAGS = -Wl,--gc-sections
define bsp-post-link
$(OBJCOPY) -O binary --strip-all $(basename $@)$(EXEEXT) \
-R entry -R exceptions $(basename $@)$(DOWNEXT)
$(default-bsp-post-link)
endef

View File

@@ -1,6 +0,0 @@
#
# The GDB LM32 simulator in GDB
#
include: testdata/disable-intrcritical-tests.tcfg

View File

@@ -1,5 +0,0 @@
#
# BSP Variant for running on simulator in GDB
#
include $(RTEMS_ROOT)/make/custom/lm32_evr.cfg

View File

@@ -1,107 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSBSPsLM32EVR
*
* @brief Global BSP definitions.
*/
/*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#ifndef LIBBSP_LM32_LM32_EVR_BSP_H
#define LIBBSP_LM32_LM32_EVR_BSP_H
/**
* @defgroup RTEMSBSPsLM32EVR LM32 EVR
*
* @ingroup RTEMSBSPsLM32
*
* @brief LM32 EVR Board Support Package.
*
* @{
*/
#include <stdint.h>
#include <bspopts.h>
#include <bsp/default-initial-extension.h>
#include <rtems.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* lm32 requires certain aligment of mbuf because unaligned uint32_t
* accesses are not handled properly.
*/
#define CPU_U32_FIX
#if defined(RTEMS_NETWORKING)
struct rtems_bsdnet_ifconfig;
extern int rtems_tsmac_driver_attach(struct rtems_bsdnet_ifconfig *config,
int attaching);
#define RTEMS_BSP_NETWORK_DRIVER_NAME "TSMAC0"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_tsmac_driver_attach
/*
* Due to a hardware design error (RJ45 connector with 10baseT magnetics)
* we are forced to use 10baseT mode.
*/
#define TSMAC_FORCE_10BASET
#endif
/* functions */
rtems_isr_entry set_vector( /* returns old vector */
rtems_isr_entry handler, /* isr routine */
rtems_vector_number vector, /* vector number */
int type /* RTEMS or RAW intr */
);
/*
* Prototypes for BSP methods that cross file boundaries
*/
void BSP_uart_polled_write(char ch);
int BSP_uart_polled_read( void );
char BSP_uart_is_character_ready(char *ch);
#ifdef __cplusplus
}
#endif
/** @} */
#endif
/* end of include file */

View File

@@ -1,180 +0,0 @@
/**
* @file
*
* @ingroup lm32_evr
*
* @brief System configuration.
*/
#ifndef __SYSTEM_CONFIG_H_
#define __SYSTEM_CONFIG_H_
#define FPGA_DEVICE_FAMILY "ECP2M"
#define PLATFORM_NAME "platform1"
#define USE_PLL (0)
#define CPU_FREQUENCY (75000000)
/* FOUND 1 CPU UNIT(S) */
/*
* CPU Instance LM32 component configuration
*/
#define CPU_NAME "LM32"
#define CPU_EBA (0x04000000)
#define CPU_DIVIDE_ENABLED (1)
#define CPU_SIGN_EXTEND_ENABLED (1)
#define CPU_MULTIPLIER_ENABLED (1)
#define CPU_SHIFT_ENABLED (1)
#define CPU_DEBUG_ENABLED (1)
#define CPU_HW_BREAKPOINTS_ENABLED (0)
#define CPU_NUM_HW_BREAKPOINTS (0)
#define CPU_NUM_WATCHPOINTS (0)
#define CPU_ICACHE_ENABLED (1)
#define CPU_ICACHE_SETS (512)
#define CPU_ICACHE_ASSOC (1)
#define CPU_ICACHE_BYTES_PER_LINE (16)
#define CPU_DCACHE_ENABLED (1)
#define CPU_DCACHE_SETS (512)
#define CPU_DCACHE_ASSOC (1)
#define CPU_DCACHE_BYTES_PER_LINE (16)
#define CPU_DEBA (0x0C000000)
#define CPU_CHARIO_IN (1)
#define CPU_CHARIO_OUT (1)
#define CPU_CHARIO_TYPE "JTAG UART"
/*
* gpio component configuration
*/
#define GPIO_NAME "gpio"
#define GPIO_BASE_ADDRESS (0x80004000)
#define GPIO_SIZE (128)
#define GPIO_CHARIO_IN (0)
#define GPIO_CHARIO_OUT (0)
#define GPIO_ADDRESS_LOCK (1)
#define GPIO_DISABLE (0)
#define GPIO_OUTPUT_PORTS_ONLY (1)
#define GPIO_INPUT_PORTS_ONLY (0)
#define GPIO_TRISTATE_PORTS (0)
#define GPIO_BOTH_INPUT_AND_OUTPUT (0)
#define GPIO_DATA_WIDTH (4)
#define GPIO_INPUT_WIDTH (1)
#define GPIO_OUTPUT_WIDTH (1)
#define GPIO_IRQ_MODE (0)
#define GPIO_LEVEL (0)
#define GPIO_EDGE (0)
#define GPIO_EITHER_EDGE_IRQ (0)
#define GPIO_POSE_EDGE_IRQ (0)
#define GPIO_NEGE_EDGE_IRQ (0)
/*
* uart component configuration
*/
#define UART_NAME "uart"
#define UART_BASE_ADDRESS (0x80006000)
#define UART_SIZE (128)
#define UART_IRQ (0)
#define UART_CHARIO_IN (1)
#define UART_CHARIO_OUT (1)
#define UART_CHARIO_TYPE "RS-232"
#define UART_ADDRESS_LOCK (1)
#define UART_DISABLE (0)
#define UART_MODEM (0)
#define UART_ADDRWIDTH (5)
#define UART_DATAWIDTH (8)
#define UART_BAUD_RATE (115200)
#define UART_IB_SIZE (4)
#define UART_OB_SIZE (4)
#define UART_BLOCK_WRITE (1)
#define UART_BLOCK_READ (1)
#define UART_DATA_BITS (8)
#define UART_STOP_BITS (1)
#define UART_FIFO (0)
#define UART_INTERRUPT_DRIVEN (1)
/*
* ebr component configuration
*/
#define EBR_NAME "ebr"
#define EBR_BASE_ADDRESS (0x04000000)
#define EBR_SIZE (32768)
#define EBR_IS_READABLE (1)
#define EBR_IS_WRITABLE (1)
#define EBR_ADDRESS_LOCK (1)
#define EBR_DISABLE (0)
#define EBR_EBR_DATA_WIDTH (32)
#define EBR_INIT_FILE_NAME "none"
#define EBR_INIT_FILE_FORMAT "hex"
/*
* ts_mac_core component configuration
*/
#define TS_MAC_CORE_NAME "ts_mac_core"
#define TS_MAC_CORE_BASE_ADDRESS (0x80008000)
#define TS_MAC_CORE_SIZE (8192)
#define TS_MAC_CORE_IRQ (2)
#define TS_MAC_CORE_CHARIO_IN (0)
#define TS_MAC_CORE_CHARIO_OUT (0)
#define TS_MAC_CORE_ADDRESS_LOCK (1)
#define TS_MAC_CORE_DISABLE (0)
#define TS_MAC_CORE_STAT_REGS (1)
#define TS_MAC_CORE_TXRX_FIFO_DEPTH (512)
#define TS_MAC_CORE_MIIM_MODULE (1)
#define TS_MAC_CORE_NGO "l:/mrf/lattice/crio-lm32/platform1/components/ts_mac_top_v27/ipexpress/ts_mac_core/ts_mac_core.ngo"
#define TS_MAC_CORE_ISPLEVER_PRJ "l:/mrf/lattice/crio-lm32/criomico.syn"
/*
* timer0 component configuration
*/
#define TIMER0_NAME "timer0"
#define TIMER0_BASE_ADDRESS (0x80002000)
#define TIMER0_SIZE (128)
#define TIMER0_IRQ (1)
#define TIMER0_CHARIO_IN (0)
#define TIMER0_CHARIO_OUT (0)
#define TIMER0_ADDRESS_LOCK (1)
#define TIMER0_DISABLE (0)
#define TIMER0_PERIOD_NUM (20)
#define TIMER0_PERIOD_WIDTH (32)
#define TIMER0_WRITEABLE_PERIOD (1)
#define TIMER0_READABLE_SNAPSHOT (1)
#define TIMER0_START_STOP_CONTROL (1)
#define TIMER0_WATCHDOG (0)
/*
* timer1 component configuration
*/
#define TIMER1_NAME "timer1"
#define TIMER1_BASE_ADDRESS (0x8000A000)
#define TIMER1_SIZE (128)
#define TIMER1_IRQ (3)
#define TIMER1_CHARIO_IN (0)
#define TIMER1_CHARIO_OUT (0)
#define TIMER1_ADDRESS_LOCK (1)
#define TIMER1_DISABLE (0)
#define TIMER1_PERIOD_NUM (20)
#define TIMER1_PERIOD_WIDTH (32)
#define TIMER1_WRITEABLE_PERIOD (1)
#define TIMER1_READABLE_SNAPSHOT (1)
#define TIMER1_START_STOP_CONTROL (1)
#define TIMER1_WATCHDOG (0)
/*
* ddr2_sdram component configuration
*/
#define DDR2_SDRAM_NAME "ddr2_sdram"
#define DDR2_SDRAM_BASE_ADDRESS (0x08000000)
#define DDR2_SDRAM_SIZE (33554432)
#define DDR2_SDRAM_IS_READABLE (1)
#define DDR2_SDRAM_IS_WRITABLE (1)
#define DDR2_SDRAM_BST_CNT_READ (1)
#define DDR2_SDRAM_ADDRESS_LOCK (1)
#define DDR2_SDRAM_DISABLE (0)
#define DDR2_SDRAM_NGO "L:/mrf/lattice/cRIO-LM32/platform1/components/wb_ddr2_ctl_v65/ipexpress/ddr2_sdram/ddr2_sdram.ngo"
#define DDR2_SDRAM_ISPLEVER_PRJ "l:/mrf/lattice/crio-lm32/criomico.syn"
#define DDR2_SDRAM_PARAM_FILE "ddr_p_eval/$/src/params/ddr_sdram_mem_params.v"
#define DDR2_SDRAM_MEM_TOP "ddr_p_eval/$/src/rtl/top/@/ddr_sdram_mem_top.v"
#endif /* __SYSTEM_CONFIG_H_ */

View File

@@ -1,40 +0,0 @@
/**
* @file
*
* @ingroup lm32_evr
*
* @brief TM27 timing test routines.
*/
/*
* tm27.h
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef _RTEMS_TMTEST27
#error "This is an RTEMS internal file you must not include directly."
#endif
#ifndef __tm27_h
#define __tm27_h
/*
* Stuff for Time Test 27
*/
#define MUST_WAIT_FOR_INTERRUPT 0
#define TM27_USE_VECTOR_HANDLER
#define Install_tm27_vector( handler ) set_vector( (handler), 0, 1 )
#define Cause_tm27_intr() /* empty */
#define Clear_tm27_intr() /* empty */
#define Lower_tm27_intr() /* empty */
#endif

View File

@@ -1,313 +0,0 @@
OUTPUT_FORMAT("elf32-lm32", "elf32-lm32",
"elf32-lm32")
OUTPUT_ARCH(lm32)
ENTRY(start)
STARTUP(start.o)
/* Do we need any of these for elf?
__DYNAMIC = 0; */
/*
* Declare some sizes. Heap is sized at whatever ram space is left.
*/
RamBase = DEFINED(RamBase) ? RamBase : 0x08000000;
RamSize = DEFINED(RamSize) ? RamSize : 32M;
RamEnd = RamBase + RamSize;
HeapSize = DEFINED(HeapSize) ? HeapSize : 2M;
MEMORY {
ebr : ORIGIN = 0x04000000 , LENGTH = 32k
sdram : ORIGIN = 0x08000000 , LENGTH = 32M
}
SECTIONS
{
.boot :
{
KEEP (*(.boot))
} > ebr
/* Read-only sections, merged into text segment: */
.interp : { *(.interp) } > sdram
.hash : { *(.hash) } > sdram
.dynsym : { *(.dynsym) } > sdram
.dynstr : { *(.dynstr) } > sdram
.gnu.version : { *(.gnu.version) } > sdram
.gnu.version_d : { *(.gnu.version_d) } > sdram
.gnu.version_r : { *(.gnu.version_r) } > sdram
.rela.text :
{ *(.rela.text) *(.rela.gnu.linkonce.t*) } > sdram
.rela.data :
{ *(.rela.data) *(.rela.gnu.linkonce.d*) } > sdram
.rela.rodata :
{ *(.rela.rodata*) *(.rela.gnu.linkonce.r*) } > sdram
.rela.got : { *(.rela.got) } > sdram
.rela.got1 : { *(.rela.got1) } > sdram
.rela.got2 : { *(.rela.got2) } > sdram
.rela.ctors : { *(.rela.ctors) } > sdram
.rela.dtors : { *(.rela.dtors) } > sdram
.rela.init : { *(.rela.init) } > sdram
.rela.fini : { *(.rela.fini) } > sdram
.rela.bss : { *(.rela.bss) } > sdram
.rela.plt : { *(.rela.plt) } > sdram
.rela.sdata : { *(.rela.sdata) } > sdram
.rela.sbss : { *(.rela.sbss) } > sdram
.rela.sdata2 : { *(.rela.sdata2) } > sdram
.rela.sbss2 : { *(.rela.sbss2) } > sdram
.rela.dyn : { *(.rela.dyn) } > sdram
.init : { KEEP(*(.init)) } > sdram
.text :
{
*(.text*)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
} > sdram
.fini : { _fini = .; KEEP(*(.fini)) } > sdram
.rodata : { *(.rodata*) KEEP (*(SORT(.rtemsroset.*))) *(.gnu.linkonce.r*) } > sdram
.rodata1 : { *(.rodata1) } > sdram
.tdata : {
_TLS_Data_begin = .;
*(.tdata .tdata.* .gnu.linkonce.td.*)
_TLS_Data_end = .;
} > sdram
.tbss : {
_TLS_BSS_begin = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
_TLS_BSS_end = .;
} > sdram
_TLS_Data_size = _TLS_Data_end - _TLS_Data_begin;
_TLS_Data_begin = _TLS_Data_size != 0 ? _TLS_Data_begin : _TLS_BSS_begin;
_TLS_Data_end = _TLS_Data_size != 0 ? _TLS_Data_end : _TLS_BSS_begin;
_TLS_BSS_size = _TLS_BSS_end - _TLS_BSS_begin;
_TLS_Size = _TLS_BSS_end - _TLS_Data_begin;
_TLS_Alignment = MAX (ALIGNOF (.tdata), ALIGNOF (.tbss));
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN(0x10000) + (. & (0x10000 - 1));
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { *(.preinit_array) } >sdram
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { *(.init_array) } >sdram
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { *(.fini_array) } >sdram
PROVIDE (__fini_array_end = .);
/* _SDA2_BASE_ = __SDATA2_START__ + 0x8000; */
.sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } >sdram
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
/* avoid empty sdata2/sbss2 area -- __eabi would not set up r2
* which may be important if run-time loading is used
*/
. += 1;
} >sdram
.eh_frame : { *.(eh_frame) } >sdram
/* NOTE: if the BSP uses page tables, the correctness of
* '_etext' (and __DATA_START__) is CRUCIAL - otherwise,
* an invalid mapping may result!!!
*/
_etext = .;
PROVIDE (etext = .);
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. It would
be more correct to do this:
. = ALIGN(0x40000) + (ALIGN(8) & (0x40000 - 1));
The current expression does not correctly handle the case of a
text segment ending precisely at the end of a page; it causes the
data segment to skip a page. The above expression does not have
this problem, but it will currently (2/95) cause BFD to allocate
a single segment, combining both text and data, for this case.
This will prevent the text segment from being shared among
multiple executions of the program; I think that is more
important than losing a page of the virtual address space (note
that no actual memory is lost; the page which is skipped can not
be referenced). */
. = ALIGN(0x1000);
.data ALIGN(0x1000) :
{
/* NOTE: if the BSP uses page tables, the correctness of
* '__DATA_START__' (and _etext) is CRUCIAL - otherwise,
* an invalid mapping may result!!!
*/
PROVIDE(__DATA_START__ = ABSOLUTE(.) );
*(.data .data.* .gnu.linkonce.d*)
KEEP (*(SORT(.rtemsrwset.*)))
SORT(CONSTRUCTORS)
} > sdram
.data1 : { *(.data1) } > sdram
PROVIDE (__EXCEPT_START__ = .);
.gcc_except_table : {
*(.gcc_except_table)
*(.gcc_except_table.*)
} > sdram
PROVIDE (__EXCEPT_END__ = .);
.got1 : { *(.got1) } > sdram
/* Put .ctors and .dtors next to the .got2 section, so that the pointers
get relocated with -mrelocatable. Also put in the .fixup pointers.
The current compiler no longer needs this, but keep it around for 2.7.2 */
PROVIDE (_GOT2_START_ = .);
.got2 : { *(.got2) } > sdram
.dynamic : { *(.dynamic) } > sdram
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} > sdram
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} > sdram
PROVIDE (_FIXUP_START_ = .);
.fixup : { *(.fixup) } > sdram
PROVIDE (_FIXUP_END_ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (_GOT_START_ = .);
.got : { *(.got) } > sdram
.got.plt : { *(.got.plt) } > sdram
PROVIDE (_GOT_END_ = .);
.jcr : { KEEP (*(.jcr)) } > sdram
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
/* _SDA_BASE_ = __SDATA_START__ + 0x8000; */
.sdata : { *(.sdata*) *(.gnu.linkonce.s.*) } >sdram
_edata = .;
_gp = .;
PROVIDE (edata = .);
.sbss :
{
_clear_start = .;
PROVIDE (__sbss_start = .);
*(.dynsbss)
*(.sbss* .gnu.linkonce.sb.*)
*(.scommon)
/* avoid empty sdata/sbss area -- __eabi would not set up r13
* which may be important if run-time loading is used
*/
. += 1;
. = ALIGN(16);
PROVIDE (__sbss_end = .);
} > sdram
.plt : { *(.plt) } > sdram
.bss :
{
PROVIDE (__bss_start = .);
*(.dynbss)
*(.bss .bss* .gnu.linkonce.b*)
*(COMMON)
. = ALIGN(16);
_end = . ;
__rtems_end = . ;
PROVIDE (end = .);
. = ALIGN (16);
_clear_end = .;
} > sdram
.noinit (NOLOAD) : {
*(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*)))
} > sdram
.rtemsstack (NOLOAD) : {
*(SORT(.rtemsstack.*))
WorkAreaBase = .;
} > sdram
/DISCARD/ :
{
*(.comment)
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
/* Addition to let linker know about custom section for GDB pretty-printing support. */
.debug_gdb_scripts 0 : { *(.debug_gdb_scripts) }
}

View File

@@ -1,56 +0,0 @@
milkymist
=========
Full RTEMS port to the Milkymist One. Supports Milkymist SoC 1.0.x.
Includes drivers for:
- Multi-standard video input (PAL/SECAM/NTSC)
- Two DMX512 (RS485) ports
- MIDI IN and MIDI OUT ports
- VGA output
- AC'97 audio
- NOR flash
- 10/100 Ethernet
- Memory card (experimental and incomplete)
- USB host connectors (input devices only, using the softusb-input firmware)
- RC5 infrared receiver
- RS232 debug port
For more information: http://www.milkymist.org/
UART
----
Initialization:
set the CSR_UART_DIVISOR to the correct VALUE,
depending on the internal frequency of the LatticeMico32 softcore.
for the ML401 board, this value is calculated using this formula : clk_frequency/230400/16
clk_frequency = 100000000 Hz
=> we must set CSR_UART_DIVISOR to 27
How to send a byte to uart :
```c
void writechar(char c)
{
CSR_UART_RXTX = c;
while(!(irq_pending() & IRQ_UARTTX));
irq_ack(IRQ_UARTTX);
}
```
How to receive a byte from uart :
```c
char readchar()
{
char c;
while(!(irq_pending() & IRQ_UARTRX));
irq_ack(IRQ_UARTRX);
c = CSR_UART_RXTX;
return c;
}
```

View File

@@ -1,29 +0,0 @@
#
# Config file for the milkymist BSP
#
# Choices for CPU_MODEL:
# tiny (no cache)
# standard (instruction cache)
# fast (instruction and data cache)
RTEMS_CPU = lm32
include $(RTEMS_ROOT)/make/custom/default.cfg
# This contains the compiler options necessary to select the CPU model
# and (hopefully) optimize for it.
CPU_CFLAGS = -mbarrel-shift-enabled -mmultiply-enabled \
-mdivide-enabled -msign-extend-enabled
# optimize flag: typically -O2
CFLAGS_OPTIMIZE_V = -O2 -g
CFLAGS_OPTIMIZE_V += -ffunction-sections -fdata-sections
LDFLAGS = -Wl,--gc-sections
define bsp-post-link
$(OBJCOPY) -O binary --strip-all $(basename $@)$(EXEEXT) \
-R entry -R exceptions $(basename $@)$(DOWNEXT)
$(default-bsp-post-link)
endef

View File

@@ -1,66 +0,0 @@
/**
* @file
*
* @ingroup RTEMSBSPsLM32Milkymist
*
* @brief Global BSP definitions.
*/
/* bsp.h
*
* This include file contains all board IO definitions.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2011 Sebastien Bourdeauducq
*/
#ifndef LIBBSP_LM32_MILKYMIST_BSP_H
#define LIBBSP_LM32_MILKYMIST_BSP_H
#include <stdint.h>
#include <bspopts.h>
#include <bsp/default-initial-extension.h>
#include <rtems.h>
/**
* @defgroup RTEMSBSPsLM32Milkymist Milkymist
*
* @ingroup RTEMSBSPsLM32
*
* @brief Milkymist Board Support Package.
*
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
#define BSP_HAS_FRAME_BUFFER 1
/*
* lm32 requires certain aligment of mbuf because unaligned uint32_t
* accesses are not handled properly.
*/
#define CPU_U32_FIX
#if defined(RTEMS_NETWORKING)
struct rtems_bsdnet_ifconfig;
extern int rtems_minimac_driver_attach (struct rtems_bsdnet_ifconfig *config,
int attaching);
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_minimac_driver_attach
#define RTEMS_BSP_NETWORK_DRIVER_NAME "minimac0"
#endif
#ifdef __cplusplus
}
#endif
/** @} */
#endif

View File

@@ -1,329 +0,0 @@
/**
* @file
*
* @ingroup lm32_milkymist
*
* @brief System configuration.
*/
/* system_conf.h
* Global System conf
*
* Milkymist port of RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#ifndef __SYSTEM_CONFIG_H_
#define __SYSTEM_CONFIG_H_
#define UART_BAUD_RATE (115200)
/* Clock frequency */
#define MM_FREQUENCY (0xe0001074)
/* FML bridge */
#define FMLBRG_FLUSH_BASE (0xc8000000)
#define FMLBRG_LINE_LENGTH (32)
#define FMLBRG_LINE_COUNT (512)
/* UART */
#define MM_UART_RXTX (0xe0000000)
#define MM_UART_DIV (0xe0000004)
#define MM_UART_STAT (0xe0000008)
#define MM_UART_CTRL (0xe000000c)
#define UART_STAT_THRE (0x1)
#define UART_STAT_RX_EVT (0x2)
#define UART_STAT_TX_EVT (0x4)
#define UART_CTRL_RX_INT (0x1)
#define UART_CTRL_TX_INT (0x2)
#define UART_CTRL_THRU (0x4)
/* Timers */
#define MM_TIMER1_COMPARE (0xe0001024)
#define MM_TIMER1_COUNTER (0xe0001028)
#define MM_TIMER1_CONTROL (0xe0001020)
#define MM_TIMER0_COMPARE (0xe0001014)
#define MM_TIMER0_COUNTER (0xe0001018)
#define MM_TIMER0_CONTROL (0xe0001010)
#define TIMER_ENABLE (0x01)
#define TIMER_AUTORESTART (0x02)
/* GPIO */
#define MM_GPIO_IN (0xe0001000)
#define MM_GPIO_OUT (0xe0001004)
#define MM_GPIO_INTEN (0xe0001008)
#define GPIO_BTN1 (0x00000001)
#define GPIO_BTN2 (0x00000002)
#define GPIO_BTN3 (0x00000004)
#define GPIO_PCBREV0 (0x00000008)
#define GPIO_PCBREV1 (0x00000010)
#define GPIO_PCBREV2 (0x00000020)
#define GPIO_PCBREV3 (0x00000040)
#define GPIO_LED1 (0x00000001)
#define GPIO_LED2 (0x00000002)
/* System ID and reset */
#define MM_SYSTEM_ID (0xe000107c)
/* ICAP */
#define MM_ICAP (0xe0001040)
#define ICAP_READY (0x01)
#define ICAP_CE (0x10000)
#define ICAP_WRITE (0x20000)
/* VGA */
#define MM_VGA_RESET (0xe0003000)
#define MM_VGA_HRES (0xe0003004)
#define MM_VGA_HSYNC_START (0xe0003008)
#define MM_VGA_HSYNC_END (0xe000300C)
#define MM_VGA_HSCAN (0xe0003010)
#define MM_VGA_VRES (0xe0003014)
#define MM_VGA_VSYNC_START (0xe0003018)
#define MM_VGA_VSYNC_END (0xe000301C)
#define MM_VGA_VSCAN (0xe0003020)
#define MM_VGA_BASEADDRESS (0xe0003024)
#define MM_VGA_BASEADDRESS_ACT (0xe0003028)
#define MM_VGA_BURST_COUNT (0xe000302C)
#define MM_VGA_DDC (0xe0003030)
#define MM_VGA_CLKSEL (0xe0003034)
#define VGA_RESET (0x01)
#define VGA_DDC_SDAIN (0x1)
#define VGA_DDC_SDAOUT (0x2)
#define VGA_DDC_SDAOE (0x4)
#define VGA_DDC_SDC (0x8)
/* Ethernet */
#define MM_MINIMAC_SETUP (0xe0008000)
#define MM_MINIMAC_MDIO (0xe0008004)
#define MM_MINIMAC_STATE0 (0xe0008008)
#define MM_MINIMAC_COUNT0 (0xe000800C)
#define MM_MINIMAC_STATE1 (0xe0008010)
#define MM_MINIMAC_COUNT1 (0xe0008014)
#define MM_MINIMAC_TXCOUNT (0xe0008018)
#define MINIMAC_RX0_BASE (0xb0000000)
#define MINIMAC_RX1_BASE (0xb0000800)
#define MINIMAC_TX_BASE (0xb0001000)
#define MINIMAC_SETUP_PHYRST (0x1)
#define MINIMAC_STATE_EMPTY (0x0)
#define MINIMAC_STATE_LOADED (0x1)
#define MINIMAC_STATE_PENDING (0x2)
/* AC97 */
#define MM_AC97_CRCTL (0xe0005000)
#define AC97_CRCTL_RQEN (0x01)
#define AC97_CRCTL_WRITE (0x02)
#define MM_AC97_CRADDR (0xe0005004)
#define MM_AC97_CRDATAOUT (0xe0005008)
#define MM_AC97_CRDATAIN (0xe000500C)
#define MM_AC97_DCTL (0xe0005010)
#define MM_AC97_DADDRESS (0xe0005014)
#define MM_AC97_DREMAINING (0xe0005018)
#define MM_AC97_UCTL (0xe0005020)
#define MM_AC97_UADDRESS (0xe0005024)
#define MM_AC97_UREMAINING (0xe0005028)
#define AC97_SCTL_EN (0x01)
#define AC97_MAX_DMASIZE (0x3fffc)
/* SoftUSB */
#define MM_SOFTUSB_CONTROL (0xe000f000)
#define SOFTUSB_CONTROL_RESET (0x1)
#define MM_SOFTUSB_PMEM_BASE (0xa0000000)
#define MM_SOFTUSB_DMEM_BASE (0xa0020000)
#define SOFTUSB_PMEM_SIZE (1 << 13)
#define SOFTUSB_DMEM_SIZE (1 << 13)
/* PFPU */
#define MM_PFPU_CTL (0xe0006000)
#define PFPU_CTL_START (0x01)
#define PFPU_CTL_BUSY (0x01)
#define MM_PFPU_MESHBASE (0xe0006004)
#define MM_PFPU_HMESHLAST (0xe0006008)
#define MM_PFPU_VMESHLAST (0xe000600C)
#define MM_PFPU_CODEPAGE (0xe0006010)
#define MM_PFPU_DREGBASE (0xe0006400)
#define MM_PFPU_CODEBASE (0xe0006800)
#define PFPU_PAGESIZE (512)
#define PFPU_SPREG_COUNT (2)
#define PFPU_REG_X (0)
#define PFPU_REG_Y (1)
/* TMU */
#define MM_TMU_CTL (0xe0007000)
#define TMU_CTL_START (0x01)
#define TMU_CTL_BUSY (0x01)
#define TMU_CTL_CHROMAKEY (0x02)
#define MM_TMU_HMESHLAST (0xe0007004)
#define MM_TMU_VMESHLAST (0xe0007008)
#define MM_TMU_BRIGHTNESS (0xe000700C)
#define MM_TMU_CHROMAKEY (0xe0007010)
#define MM_TMU_VERTICESADR (0xe0007014)
#define MM_TMU_TEXFBUF (0xe0007018)
#define MM_TMU_TEXHRES (0xe000701C)
#define MM_TMU_TEXVRES (0xe0007020)
#define MM_TMU_TEXHMASK (0xe0007024)
#define MM_TMU_TEXVMASK (0xe0007028)
#define MM_TMU_DSTFBUF (0xe000702C)
#define MM_TMU_DSTHRES (0xe0007030)
#define MM_TMU_DSTVRES (0xe0007034)
#define MM_TMU_DSTHOFFSET (0xe0007038)
#define MM_TMU_DSTVOFFSET (0xe000703C)
#define MM_TMU_DSTSQUAREW (0xe0007040)
#define MM_TMU_DSTSQUAREH (0xe0007044)
#define MM_TMU_ALPHA (0xe0007048)
/* Memory card */
#define MM_MEMCARD_CLK2XDIV (0xe0004000)
#define MM_MEMCARD_ENABLE (0xe0004004)
#define MEMCARD_ENABLE_CMD_TX (0x1)
#define MEMCARD_ENABLE_CMD_RX (0x2)
#define MEMCARD_ENABLE_DAT_TX (0x4)
#define MEMCARD_ENABLE_DAT_RX (0x8)
#define MM_MEMCARD_PENDING (0xe0004008)
#define MEMCARD_PENDING_CMD_TX (0x1)
#define MEMCARD_PENDING_CMD_RX (0x2)
#define MEMCARD_PENDING_DAT_TX (0x4)
#define MEMCARD_PENDING_DAT_RX (0x8)
#define MM_MEMCARD_START (0xe000400c)
#define MEMCARD_START_CMD_RX (0x1)
#define MEMCARD_START_DAT_RX (0x2)
#define MM_MEMCARD_CMD (0xe0004010)
#define MM_MEMCARD_DAT (0xe0004014)
/* DMX */
#define MM_DMX_TX(x) (0xe000c000+4*(x))
#define MM_DMX_THRU (0xe000c800)
#define MM_DMX_RX(x) (0xe000d000+4*(x))
/* MIDI */
#define MM_MIDI_RXTX (0xe000b000)
#define MM_MIDI_DIV (0xe000b004)
#define MM_MIDI_STAT (0xe000b008)
#define MM_MIDI_CTRL (0xe000b00c)
#define MIDI_STAT_THRE (0x1)
#define MIDI_STAT_RX_EVT (0x2)
#define MIDI_STAT_TX_EVT (0x4)
#define MIDI_CTRL_RX_INT (0x1)
#define MIDI_CTRL_TX_INT (0x2)
#define MIDI_CTRL_THRU (0x4)
/* IR */
#define MM_IR_RX (0xe000e000)
/* Video input */
#define MM_BT656_I2C (0xe000a000)
#define MM_BT656_FILTERSTATUS (0xe000a004)
#define MM_BT656_BASE (0xe000a008)
#define MM_BT656_MAXBURSTS (0xe000a00c)
#define MM_BT656_DONEBURSTS (0xe000a010)
#define BT656_I2C_SDAIN (0x1)
#define BT656_I2C_SDAOUT (0x2)
#define BT656_I2C_SDAOE (0x4)
#define BT656_I2C_SDC (0x8)
#define BT656_FILTER_FIELD1 (0x1)
#define BT656_FILTER_FIELD2 (0x2)
#define BT656_FILTER_INFRAME (0x4)
/* Interrupts */
#define MM_IRQ_UART (0)
#define MM_IRQ_GPIO (1)
#define MM_IRQ_TIMER0 (2)
#define MM_IRQ_TIMER1 (3)
#define MM_IRQ_AC97CRREQUEST (4)
#define MM_IRQ_AC97CRREPLY (5)
#define MM_IRQ_AC97DMAR (6)
#define MM_IRQ_AC97DMAW (7)
#define MM_IRQ_PFPU (8)
#define MM_IRQ_TMU (9)
#define MM_IRQ_ETHRX (10)
#define MM_IRQ_ETHTX (11)
#define MM_IRQ_VIDEOIN (12)
#define MM_IRQ_MIDI (13)
#define MM_IRQ_IR (14)
#define MM_IRQ_USB (15)
/* Flash layout */
#define FLASH_BASE (0x80000000)
#define FLASH_OFFSET_STANDBY_BITSTREAM (0x80000000)
#define FLASH_OFFSET_RESCUE_BITSTREAM (0x800A0000)
#define FLASH_OFFSET_RESCUE_BIOS (0x80220000)
#define FLASH_OFFSET_MAC_ADDRESS (0x802200E0)
#define FLASH_OFFSET_RESCUE_SPLASH (0x80240000)
#define FLASH_OFFSET_RESCUE_APP (0x802E0000)
#define FLASH_OFFSET_REGULAR_BITSTREAM (0x806E0000)
#define FLASH_OFFSET_REGULAR_BIOS (0x80860000)
#define FLASH_OFFSET_REGULAR_SPLASH (0x80880000)
#define FLASH_OFFSET_REGULAR_APP (0x80920000)
/* MMIO */
#define MM_READ(reg) (*((volatile unsigned int *)(reg)))
#define MM_WRITE(reg, val) *((volatile unsigned int *)(reg)) = val
/* Flash partitions */
#define FLASH_SECTOR_SIZE (128*1024)
#define FLASH_PARTITION_COUNT (5)
#define FLASH_PARTITIONS { \
{ .start_address = 0x806E0000, .length = 0x0180000 }, \
{ .start_address = 0x80860000, .length = 0x0020000 }, \
{ .start_address = 0x80880000, .length = 0x00A0000 }, \
{ .start_address = 0x80920000, .length = 0x0400000 }, \
{ .start_address = 0x80D20000, .length = 0x12E0000 }, \
}
#endif /* __SYSTEM_CONFIG_H_ */

View File

@@ -1 +0,0 @@
#include <rtems/tm27-default.h>

View File

@@ -1,59 +0,0 @@
/*
* Milkymist shutdown routine
*/
/*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <bsp/bootcard.h>
#include "../include/system_conf.h"
static void reboot(void)
{
/* Writing to CSR_SYSTEM_ID causes a system reset */
MM_WRITE(MM_SYSTEM_ID, 1);
}
static void icap_write(int val, unsigned int w)
{
while (!(MM_READ(MM_ICAP) & ICAP_READY));
if (!val)
w |= ICAP_CE|ICAP_WRITE;
MM_WRITE(MM_ICAP, w);
}
static void reconf(void)
{
icap_write(0, 0xffff); /* dummy word */
icap_write(0, 0xffff); /* dummy word */
icap_write(0, 0xffff); /* dummy word */
icap_write(0, 0xffff); /* dummy word */
icap_write(1, 0xaa99); /* sync word part 1 */
icap_write(1, 0x5566); /* sync word part 2 */
icap_write(1, 0x30a1); /* write to command register */
icap_write(1, 0x0000); /* null command */
icap_write(1, 0x30a1); /* write to command register */
icap_write(1, 0x000e); /* reboot command */
icap_write(1, 0x2000); /* NOP */
icap_write(1, 0x2000); /* NOP */
icap_write(1, 0x2000); /* NOP */
icap_write(1, 0x2000); /* NOP */
icap_write(0, 0x1111); /* NULL */
icap_write(0, 0xffff); /* dummy word */
}
void bsp_reset( rtems_fatal_source source, rtems_fatal_code code )
{
if (source == RTEMS_FATAL_SOURCE_EXIT && code)
reconf();
else
reboot();
RTEMS_UNREACHABLE();
}

View File

@@ -1,311 +0,0 @@
OUTPUT_FORMAT("elf32-lm32", "elf32-lm32",
"elf32-lm32")
OUTPUT_ARCH(lm32)
ENTRY(start)
STARTUP(start.o)
/* Do we need any of these for elf?
__DYNAMIC = 0; */
/*
* Declare some sizes. Heap is sized at whatever ram space is left.
*/
RamBase = DEFINED(RamBase) ? RamBase : 0x40000000;
RamSize = DEFINED(RamSize) ? RamSize : 128M;
RamEnd = RamBase + RamSize;
HeapSize = DEFINED(HeapSize) ? HeapSize : 92M;
MEMORY {
sdram : ORIGIN = 0x40000000 , LENGTH = 128M
}
SECTIONS
{
.boot :
{
KEEP (*(.boot))
} > sdram
/* Read-only sections, merged into text segment: */
.interp : { *(.interp) } > sdram
.hash : { *(.hash) } > sdram
.dynsym : { *(.dynsym) } > sdram
.dynstr : { *(.dynstr) } > sdram
.gnu.version : { *(.gnu.version) } > sdram
.gnu.version_d : { *(.gnu.version_d) } > sdram
.gnu.version_r : { *(.gnu.version_r) } > sdram
.rela.text :
{ *(.rela.text) *(.rela.gnu.linkonce.t*) } > sdram
.rela.data :
{ *(.rela.data) *(.rela.gnu.linkonce.d*) } > sdram
.rela.rodata :
{ *(.rela.rodata*) *(.rela.gnu.linkonce.r*) } > sdram
.rela.got : { *(.rela.got) } > sdram
.rela.got1 : { *(.rela.got1) } > sdram
.rela.got2 : { *(.rela.got2) } > sdram
.rela.ctors : { *(.rela.ctors) } > sdram
.rela.dtors : { *(.rela.dtors) } > sdram
.rela.init : { *(.rela.init) } > sdram
.rela.fini : { *(.rela.fini) } > sdram
.rela.bss : { *(.rela.bss) } > sdram
.rela.plt : { *(.rela.plt) } > sdram
.rela.sdata : { *(.rela.sdata) } > sdram
.rela.sbss : { *(.rela.sbss) } > sdram
.rela.sdata2 : { *(.rela.sdata2) } > sdram
.rela.sbss2 : { *(.rela.sbss2) } > sdram
.rela.dyn : { *(.rela.dyn) } > sdram
.init : { KEEP(*(.init)) } > sdram
.text :
{
*(.text*)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
} > sdram
.fini : { _fini = .; KEEP(*(.fini)) } > sdram
.rodata : { *(.rodata*) KEEP (*(SORT(.rtemsroset.*))) *(.gnu.linkonce.r*) } > sdram
.rodata1 : { *(.rodata1) } > sdram
.tdata : {
_TLS_Data_begin = .;
*(.tdata .tdata.* .gnu.linkonce.td.*)
_TLS_Data_end = .;
} > sdram
.tbss : {
_TLS_BSS_begin = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
_TLS_BSS_end = .;
} > sdram
_TLS_Data_size = _TLS_Data_end - _TLS_Data_begin;
_TLS_Data_begin = _TLS_Data_size != 0 ? _TLS_Data_begin : _TLS_BSS_begin;
_TLS_Data_end = _TLS_Data_size != 0 ? _TLS_Data_end : _TLS_BSS_begin;
_TLS_BSS_size = _TLS_BSS_end - _TLS_BSS_begin;
_TLS_Size = _TLS_BSS_end - _TLS_Data_begin;
_TLS_Alignment = MAX (ALIGNOF (.tdata), ALIGNOF (.tbss));
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN(0x10000) + (. & (0x10000 - 1));
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { *(.preinit_array) } >sdram
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { *(.init_array) } >sdram
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { *(.fini_array) } >sdram
PROVIDE (__fini_array_end = .);
/* _SDA2_BASE_ = __SDATA2_START__ + 0xe000; */
.sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } >sdram
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
/* avoid empty sdata2/sbss2 area -- __eabi would not set up r2
* which may be important if run-time loading is used
*/
. += 1;
} >sdram
.eh_frame : { *.(eh_frame) } >sdram
/* NOTE: if the BSP uses page tables, the correctness of
* '_etext' (and __DATA_START__) is CRUCIAL - otherwise,
* an invalid mapping may result!!!
*/
_etext = .;
PROVIDE (etext = .);
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. It would
be more correct to do this:
. = ALIGN(0x40000) + (ALIGN(8) & (0x40000 - 1));
The current expression does not correctly handle the case of a
text segment ending precisely at the end of a page; it causes the
data segment to skip a page. The above expression does not have
this problem, but it will currently (2/95) cause BFD to allocate
a single segment, combining both text and data, for this case.
This will prevent the text segment from being shared among
multiple executions of the program; I think that is more
important than losing a page of the virtual address space (note
that no actual memory is lost; the page which is skipped can not
be referenced). */
. = ALIGN(0x1000);
.data ALIGN(0x1000) :
{
/* NOTE: if the BSP uses page tables, the correctness of
* '__DATA_START__' (and _etext) is CRUCIAL - otherwise,
* an invalid mapping may result!!!
*/
PROVIDE(__DATA_START__ = ABSOLUTE(.) );
*(.data .data.* .gnu.linkonce.d*)
KEEP (*(SORT(.rtemsrwset.*)))
SORT(CONSTRUCTORS)
} > sdram
.data1 : { *(.data1) } > sdram
PROVIDE (__EXCEPT_START__ = .);
.gcc_except_table : {
*(.gcc_except_table)
*(.gcc_except_table.*)
} > sdram
PROVIDE (__EXCEPT_END__ = .);
.got1 : { *(.got1) } > sdram
/* Put .ctors and .dtors next to the .got2 section, so that the pointers
get relocated with -mrelocatable. Also put in the .fixup pointers.
The current compiler no longer needs this, but keep it around for 2.7.2 */
PROVIDE (_GOT2_START_ = .);
.got2 : { *(.got2) } > sdram
.dynamic : { *(.dynamic) } > sdram
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} > sdram
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} > sdram
PROVIDE (_FIXUP_START_ = .);
.fixup : { *(.fixup) } > sdram
PROVIDE (_FIXUP_END_ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (_GOT_START_ = .);
.got : { *(.got) } > sdram
.got.plt : { *(.got.plt) } > sdram
PROVIDE (_GOT_END_ = .);
.jcr : { KEEP (*(.jcr)) } > sdram
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
/* _SDA_BASE_ = __SDATA_START__ + 0xe000; */
.sdata : { *(.sdata*) *(.gnu.linkonce.s.*) } >sdram
_edata = .;
_gp = .;
PROVIDE (edata = .);
.sbss :
{
_clear_start = .;
PROVIDE (__sbss_start = .);
*(.dynsbss)
*(.sbss* .gnu.linkonce.sb.*)
*(.scommon)
/* avoid empty sdata/sbss area -- __eabi would not set up r13
* which may be important if run-time loading is used
*/
. += 1;
. = ALIGN(16);
PROVIDE (__sbss_end = .);
} > sdram
.plt : { *(.plt) } > sdram
.bss :
{
PROVIDE (__bss_start = .);
*(.dynbss)
*(.bss .bss* .gnu.linkonce.b*)
*(COMMON)
. = ALIGN(16);
_end = . ;
__rtems_end = . ;
PROVIDE (end = .);
. = ALIGN (16);
_clear_end = .;
} > sdram
.noinit (NOLOAD) : {
*(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*)))
} > sdram
.rtemsstack (NOLOAD) : {
*(SORT(.rtemsstack.*))
WorkAreaBase = .;
} > sdram
/DISCARD/ :
{
*(.comment)
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
/* Addition to let linker know about custom section for GDB pretty-printing support. */
.debug_gdb_scripts 0 : { *(.debug_gdb_scripts) }
}

View File

@@ -1,130 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* timer.c
*
* This file manages the benchmark timer used by the RTEMS Timing
* Test Suite. Each measured time period is demarcated by calls to
* benchmark_timer_initialize() and benchmark_timer_read().
* benchmark_timer_read() usually returns the number of microseconds
* since benchmark_timer_initialize() exitted.
*
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#include <rtems.h>
#include <bsp.h>
#include <rtems/btimer.h>
#include <rtems/bspIo.h>
#include "../include/system_conf.h"
#include "../../shared/clock/clock.h"
static inline int timerread(unsigned int reg)
{
#if ON_SIMULATOR && defined(TIMER0_BASE_ADDRESS)
return *((int*)(TIMER0_BASE_ADDRESS + reg));
#elif defined(TIMER1_BASE_ADDRESS)
return *((int*)(TIMER1_BASE_ADDRESS + reg));
#else
#warning "Benchmarking timer not available!"
return 0;
#endif
}
static inline void timerwrite(unsigned int reg, int value)
{
#if ON_SIMULATOR && defined(TIMER0_BASE_ADDRESS)
*((int*)(TIMER0_BASE_ADDRESS + reg)) = value;
#elif defined(TIMER1_BASE_ADDRESS)
*((int*)(TIMER1_BASE_ADDRESS + reg)) = value;
#endif
}
bool benchmark_timer_find_average_overhead;
void benchmark_timer_initialize( void )
{
/* Set timer period */
timerwrite(LM32_CLOCK_PERIOD, 0xffffffff);
/* Stop timer */
timerwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_STOP);
/* Clear status register */
timerwrite(LM32_CLOCK_SR, 0);
/* Start timer */
timerwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_START);
}
/*
* The following controls the behavior of benchmark_timer_read().
*
* AVG_OVEREHAD is the overhead for starting and stopping the timer. It
* is usually deducted from the number returned.
*
* LEAST_VALID is the lowest number this routine should trust. Numbers
* below this are "noise" and zero is returned.
*/
#define AVG_OVERHEAD 4 /* It typically takes X.X microseconds */
/* (Y countdowns) to start/stop the timer. */
/* This value is in microseconds. */
#define LEAST_VALID 4 /* Don't trust a clicks value lower than this */
benchmark_timer_t benchmark_timer_read( void )
{
uint32_t ticks;
uint32_t total;
uint32_t status;
ticks = 0xffffffff - timerread(LM32_CLOCK_SNAPSHOT);
status = timerread(LM32_CLOCK_SR);
if (status & LM32_CLOCK_SR_TO)
printk("Timer overflow!\n");
total = ticks / (CPU_FREQUENCY / 1000000);
if ( benchmark_timer_find_average_overhead == true )
return total; /* in XXX microsecond units */
else
{
if ( total < LEAST_VALID )
return 0; /* below timer resolution */
/*
* Somehow convert total into microseconds
*/
return (total - AVG_OVERHEAD);
}
}
void benchmark_timer_disable_subtracting_average_overhead(
bool find_flag
)
{
benchmark_timer_find_average_overhead = find_flag;
}

View File

@@ -1,90 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Clock device driver for Lattice Mico32 (lm32).
*/
/*
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#include <bsp.h>
#include "../include/system_conf.h"
#include "clock.h"
#include "bspopts.h"
#if LM32_ON_SIMULATOR
#define CLOCK_DRIVER_USE_FAST_IDLE 1
#endif
static inline int clockread(unsigned int reg)
{
return *((int*)(TIMER0_BASE_ADDRESS + reg));
}
static inline void clockwrite(unsigned int reg, int value)
{
*((int*)(TIMER0_BASE_ADDRESS + reg)) = value;
}
/*
* The interrupt vector number associated with the clock tick device
* driver.
*/
#define CLOCK_VECTOR ( TIMER0_IRQ )
#define CLOCK_IRQMASK ( 1 << CLOCK_VECTOR )
#define Clock_driver_support_at_tick(arg) \
do { \
/* Clear overflow flag */ \
clockwrite(LM32_CLOCK_SR, 0); \
lm32_interrupt_ack(CLOCK_IRQMASK); \
} while (0)
#define Clock_driver_support_install_isr(_new ) \
set_vector( _new, CLOCK_VECTOR, 1 )
static void Clock_driver_support_initialize_hardware(void)
{
/* Set clock period */
clockwrite(LM32_CLOCK_PERIOD,
(CPU_FREQUENCY /
(1000000 / rtems_configuration_get_microseconds_per_tick())));
/* Enable clock interrupts and start in continuous mode */
clockwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_ITO |
LM32_CLOCK_CR_CONT |
LM32_CLOCK_CR_START);
lm32_interrupt_unmask(CLOCK_IRQMASK);
}
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
#include "../../../shared/dev/clock/clockimpl.h"

View File

@@ -1,74 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
* @ingroup lm32_clock
* @brief LatticeMico32 Timer (Clock) definitions
*/
/*
* This file contains definitions for LatticeMico32 Timer (Clock)
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
/**
* @defgroup lm32_clock LM32 Clock
* @ingroup RTEMSBSPsLM32Shared
* @brief LatticeMico32 Timer (Clock) definitions.
* @{
*/
#ifndef _BSPCLOCK_H
#define _BSPCLOCK_H
/** @brief Status Register */
#define LM32_CLOCK_SR (0x0000)
#define LM32_CLOCK_SR_TO (0x0001)
#define LM32_CLOCK_SR_RUN (0x0002)
/** @brief Control Register */
#define LM32_CLOCK_CR (0x0004)
#define LM32_CLOCK_CR_ITO (0x0001)
#define LM32_CLOCK_CR_CONT (0x0002)
#define LM32_CLOCK_CR_START (0x0004)
#define LM32_CLOCK_CR_STOP (0x0008)
/** @brief Period Register */
#define LM32_CLOCK_PERIOD (0x0008)
/** @brief Snapshot Register */
#define LM32_CLOCK_SNAPSHOT (0x000C)
#endif /* _BSPCLOCK_H */
/** @} */

View File

@@ -1,197 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Console driver for Lattice Mico32 (lm32).
*/
/*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#define NO_BSP_INIT
#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/libio.h>
#include <rtems/console.h>
/* console_initialize
*
* This routine initializes the console IO driver.
*/
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
printk("console_initialize\n");
status = rtems_io_register_name(
"/dev/console",
major,
(rtems_device_minor_number) 0
);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
return RTEMS_SUCCESSFUL;
}
/* inbyte
*
* This routine reads a character from the SOURCE.
*/
static int inbyte( void )
{
/*
* If polling, wait until a character is available.
*/
return BSP_uart_polled_read();
}
/* outbyte
*
* This routine transmits a character out the SOURCE. It may support
* XON/XOFF flow control.
*/
static void outbyte(
char ch
)
{
/*
* If polling, wait for the transmitter to be ready.
* Check for flow control requests and process.
* Then output the character.
*/
BSP_uart_polled_write(ch);
}
/*
* Open entry point
*/
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return RTEMS_SUCCESSFUL;
}
/*
* Close entry point
*/
rtems_device_driver console_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return RTEMS_SUCCESSFUL;
}
/*
* read bytes from the serial port. We only have stdin.
*/
rtems_device_driver console_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_libio_rw_args_t *rw_args;
char *buffer;
int maximum;
int count = 0;
rw_args = (rtems_libio_rw_args_t *) arg;
buffer = rw_args->buffer;
maximum = rw_args->count;
for (count = 0; count < maximum; count++) {
buffer[ count ] = inbyte();
if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
buffer[ count++ ] = '\n';
break;
}
}
rw_args->bytes_moved = count;
return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
}
/*
* write bytes to the serial port. Stdout and stderr are the same.
*/
rtems_device_driver console_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
int count;
int maximum;
rtems_libio_rw_args_t *rw_args;
char *buffer;
rw_args = (rtems_libio_rw_args_t *) arg;
buffer = rw_args->buffer;
maximum = rw_args->count;
for (count = 0; count < maximum; count++) {
if ( buffer[ count ] == '\n') {
outbyte('\r');
}
outbyte( buffer[ count ] );
}
rw_args->bytes_moved = maximum;
return 0;
}
/*
* IO Control entry point
*/
rtems_device_driver console_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return RTEMS_SUCCESSFUL;
}
BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write;
BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read;

View File

@@ -1,92 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Uart driver for Lattice Mico32 (lm32) UART
*/
/*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#include "../include/system_conf.h"
#include "uart.h"
#include <bsp.h>
#include <rtems/libio.h>
static inline int uartread(unsigned int reg)
{
return *((int*)(UART_BASE_ADDRESS + reg));
}
static inline void uartwrite(unsigned int reg, int value)
{
*((int*)(UART_BASE_ADDRESS + reg)) = value;
}
void BSP_uart_init(int baud)
{
/* Disable UART interrupts */
uartwrite(LM32_UART_IER, 0);
/* Line control 8 bit, 1 stop, no parity */
uartwrite(LM32_UART_LCR, LM32_UART_LCR_8BIT);
/* Modem control, DTR = 1, RTS = 1 */
uartwrite(LM32_UART_MCR, LM32_UART_MCR_DTR | LM32_UART_MCR_RTS);
/* Set baud rate */
uartwrite(LM32_UART_DIV, CPU_FREQUENCY/baud);
}
void BSP_uart_polled_write(char ch)
{
/* Insert CR before LF */
if (ch == '\n')
BSP_uart_polled_write('\r');
/* Wait until THR is empty. */
while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_THRE));
uartwrite(LM32_UART_RBR, ch);
}
int BSP_uart_polled_read( void )
{
/* Wait until there is a byte in RBR */
while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_DR));
return (int) uartread(LM32_UART_RBR);
}
char BSP_uart_is_character_ready(char *ch)
{
if (uartread(LM32_UART_LSR) & LM32_UART_LSR_DR)
{
*ch = (char) uartread(LM32_UART_RBR);
return true;
}
*ch = '0';
return false;
}

View File

@@ -1,121 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
* @ingroup RTEMSBSPsLM32Shared lm32_uart
* @brief LatticeMico32 UART definitions
*/
/*
* This file contains definitions for LatticeMico32 UART
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
/**
* @defgroup lm32_uart LM32 UART
* @ingroup RTEMSBSPsLM32Shared
* @brief LatticeMico32 UART definitions
* @{
*/
#ifndef _BSPUART_H
#define _BSPUART_H
void BSP_uart_init(int baud);
/* Receive buffer register / transmit holding register */
#define LM32_UART_RBR (0x0000)
/* Interrupt enable register */
#define LM32_UART_IER (0x0004)
#define LM32_UART_IER_RBRI (0x0001)
#define LM32_UART_IER_THRI (0x0002)
#define LM32_UART_IER_RLSI (0x0004)
#define LM32_UART_IER_MSI (0x0008)
/* Interrupt identification register */
#define LM32_UART_IIR (0x0008)
#define LM32_UART_IIR_STAT (0x0001)
#define LM32_UART_IIR_ID0 (0x0002)
#define LM32_UART_IIR_ID1 (0x0004)
/* Line control register */
#define LM32_UART_LCR (0x000C)
#define LM32_UART_LCR_WLS0 (0x0001)
#define LM32_UART_LCR_WLS1 (0x0002)
#define LM32_UART_LCR_STB (0x0004)
#define LM32_UART_LCR_PEN (0x0008)
#define LM32_UART_LCR_EPS (0x0010)
#define LM32_UART_LCR_SP (0x0020)
#define LM32_UART_LCR_SB (0x0040)
#define LM32_UART_LCR_5BIT (0)
#define LM32_UART_LCR_6BIT (LM32_UART_LCR_WLS0)
#define LM32_UART_LCR_7BIT (LM32_UART_LCR_WLS1)
#define LM32_UART_LCR_8BIT (LM32_UART_LCR_WLS1 | LM32_UART_LCR_WLS0)
/* Modem control register */
#define LM32_UART_MCR (0x0010)
#define LM32_UART_MCR_DTR (0x0001)
#define LM32_UART_MCR_RTS (0x0002)
/* Line status register */
#define LM32_UART_LSR (0x0014)
#define LM32_UART_LSR_DR (0x0001)
#define LM32_UART_LSR_OE (0x0002)
#define LM32_UART_LSR_PE (0x0004)
#define LM32_UART_LSR_FE (0x0008)
#define LM32_UART_LSR_BI (0x0010)
#define LM32_UART_LSR_THRE (0x0020)
#define LM32_UART_LSR_TEMT (0x0040)
/* Modem status register */
#define LM32_UART_MSR (0x0018)
#define LM32_UART_MSR_DCTS (0x0001)
#define LM32_UART_MSR_DDSR (0x0002)
#define LM32_UART_MSR_TERI (0x0004)
#define LM32_UART_MSR_DDCD (0x0008)
#define LM32_UART_MSR_CTS (0x0010)
#define LM32_UART_MSR_DSR (0x0020)
#define LM32_UART_MSR_RI (0x0040)
#define LM32_UART_MSR_DCD (0x0000)
/* Baud-rate divisor register */
#define LM32_UART_DIV (0x001C)
#endif /* _BSPUART_H */
/** @} */

View File

@@ -1,31 +0,0 @@
/**
* @file
*
* @ingroup RTEMSImplDoxygen
*
* @brief This header file defines lm32-specific groups.
*/
/**
* @defgroup RTEMSBSPsLM32 LatticeMicro32 (lm32)
*
* @ingroup RTEMSBSPs
*
* @brief LatticeMicro32 Board Support Packages.
*/
/**
* @defgroup RTEMSBSPsLM32Shared Shared
*
* @ingroup RTEMSBSPsLM32
*
* @brief Shared Support for LatticeMicro32 Board Support Packages.
*/
/**
* @defgroup RTEMSBSPsLM32SharedMilkymistOne Milkymist One
*
* @ingroup RTEMSBSPsLM32Shared
*
* @brief Shared Support for Milkymist One Board Support Packages.
*/

View File

@@ -1,86 +0,0 @@
GDB Stub lm32
=============
This is a thread-aware gdb stub for the lm32 architecture. It has to be
linked with the application, which should be debugged. The application has
to call 'lm32_gdb_stub_install' to setup the stub.
The stub remaps _all_ h/w exceptions to an own code (lm32-debug.S), which
saves all the registers, calls the gdb stub and restores the registers again.
The interrupt exceptions gets handled in a special way. Because we remapped
this exception, we need to do
- the same as the original one (in cpu_asm.S),
- and, as we might use an ISR for breaking into a running application with
gdb, we need to save all registers as well. To be backward compatible
the missing callee saved registers gets appended to CPU_Interrupt_frame.
There is a mapping in 'gdb_handle_break' for that.
To use this gdb stub, your bsp has to provide the following functions:
- void gdb_put_debug_char(char c)
Puts the given charater c to the debug console output. The function can
block until the character can be written to the output buffer.
- char gdb_get_debug_char(void)
Returns the character in the input buffer of the debug console. If no one
is availabe, the function must block.
- void gdb_console_init()
This function can be used to initialize the debug console. Additionally,
it should set up the ISR for the debug console to call the function
'gdb_handle_break', which is provided by the gdb stub and enable the
interrupt for a break symbol on the debug serial port. If no ISR is
provided, you won't be able to interrupt a running application.
- void gdb_ack_irq()
If an ISR is used, this function is used to acknowledge the interrupt.
NOTE: the stub don't skip a hardcoded 'break' in the code. So you have to
set the PC an instruction further in the debugger (set $pc += 4).
NOTE2: make sure you have the following CFLAGS set:
-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled
-msign-extend-enabled
Without the hardware support, it is done in software. Unfortunately, the
stub also uses some shifts and multiplies. If you step through your code,
there will be a chance that a breakpoint is set to one of that functions,
which then causes an endless loop.
EXAMPLES
```shell
char gdb_get_debug_char(void)
{
/* Wait until there is a byte in RXTX */
while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_DR));
return (char) uartread(LM32_UART_RBR);
}
void gdb_put_debug_char(char c)
{
/* Wait until RXTX is empty. */
while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_THRE));
uartwrite(LM32_UART_RBR, c);
}
extern void gdb_handle_break(
rtems_vector_number vector,
CPU_Interrupt_frame *frame
);
void gdb_console_init()
{
rtems_isr_entry old;
/* enable interrupts */
uartwrite(LM32_UART_IER, 1);
rtems_interrupt_catch((rtems_isr_entry) gdb_handle_break, DEBUG_UART_IRQ,
&old);
lm32_interrupt_unmask(1 << DEBUG_UART_IRQ);
}
void gdb_ack_irq()
{
lm32_interrupt_ack(1 << DEBUG_UART_IRQ);
}
```

View File

@@ -1,125 +0,0 @@
/**
* @file
* @ingroup lm32_gdb
* @brief definition of the interface between the stub and gdb
*/
/*
* gdb_if.h - definition of the interface between the stub and gdb
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* The following software is offered for use in the public domain.
* There is no warranty with regard to this software or its performance
* and the user must accept the software "AS IS" with all faults.
*
* THE CONTRIBUTORS DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/**
* @defgroup lm32_gdb LM32 GDB Interface
* @ingroup RTEMSBSPsLM32Shared
* @brief Definition of the interface between the stub and gdb,
* @{
*/
#ifndef _GDB_IF_H
#define _GDB_IF_H
/** @brief Max number of threads in qM response */
#define QM_MAX_THREADS (20)
struct rtems_gdb_stub_thread_info {
char display[256];
char name[256];
char more_display[256];
};
/*
* Prototypes
*/
int parse_zbreak(const char *in, int *type, unsigned char **addr, int *len);
char* mem2hstr(char *buf, const unsigned char *mem, int count);
int hstr2mem(unsigned char *mem, const char *buf, int count);
void set_mem_err(void);
unsigned char get_byte(const unsigned char *ptr);
void set_byte(unsigned char *ptr, int val);
char* thread2vhstr(char *buf, int thread);
char* thread2fhstr(char *buf, int thread);
const char* fhstr2thread(const char *buf, int *thread);
const char* vhstr2thread(const char *buf, int *thread);
char* int2fhstr(char *buf, int val);
char* int2vhstr(char *buf, int vali);
const char* fhstr2int(const char *buf, int *ival);
const char* vhstr2int(const char *buf, int *ival);
int hstr2byte(const char *buf, int *bval);
int hstr2nibble(const char *buf, int *nibble);
Thread_Control *rtems_gdb_index_to_stub_id(int);
int rtems_gdb_stub_thread_support_ok(void);
int rtems_gdb_stub_get_current_thread(void);
int rtems_gdb_stub_get_next_thread(int);
int rtems_gdb_stub_get_offsets(
unsigned char **text_addr,
unsigned char **data_addr,
unsigned char **bss_addr
);
int rtems_gdb_stub_get_thread_regs(
int thread,
unsigned int *registers
);
int rtems_gdb_stub_set_thread_regs(
int thread,
unsigned int *registers
);
void rtems_gdb_process_query(
char *inbuffer,
char *outbuffer,
int do_threads,
int thread
);
/** @brief Exception IDs */
#define LM32_EXCEPTION_RESET 0x0
#define LM32_EXCEPTION_INST_BREAKPOINT 0x1
#define LM32_EXCEPTION_INST_BUS_ERROR 0x2
#define LM32_EXCEPTION_DATA_BREAKPOINT 0x3
#define LM32_EXCEPTION_DATA_BUS_ERROR 0x4
#define LM32_EXCEPTION_DIVIDE_BY_ZERO 0x5
#define LM32_EXCEPTION_INTERRUPT 0x6
#define LM32_EXCEPTION_SYSTEM_CALL 0x7
/** @brief Breakpoint instruction */
#define LM32_BREAK 0xac000002UL
/** @brief This numbering must be consistant with GDBs numbering in gdb/lm32-tdep.c */
enum lm32_regnames {
LM32_REG_R0, LM32_REG_R1, LM32_REG_R2, LM32_REG_R3, LM32_REG_R4, LM32_REG_R5,
LM32_REG_R6, LM32_REG_R7, LM32_REG_R8, LM32_REG_R9, LM32_REG_R10,
LM32_REG_R11, LM32_REG_R12, LM32_REG_R13, LM32_REG_R14, LM32_REG_R15,
LM32_REG_R16, LM32_REG_R17, LM32_REG_R18, LM32_REG_R19, LM32_REG_R20,
LM32_REG_R21, LM32_REG_R22, LM32_REG_R23, LM32_REG_R24, LM32_REG_R25,
LM32_REG_GP, LM32_REG_FP, LM32_REG_SP, LM32_REG_RA, LM32_REG_EA, LM32_REG_BA,
LM32_REG_PC, LM32_REG_EID, LM32_REG_EBA, LM32_REG_DEBA, LM32_REG_IE, NUM_REGS
};
/* keep this in sync with the debug isr handler in lm32-debug.S */
enum lm32_int_regnames {
LM32_INT_REG_R1, LM32_INT_REG_R2, LM32_INT_REG_R3, LM32_INT_REG_R4,
LM32_INT_REG_R5, LM32_INT_REG_R6, LM32_INT_REG_R7, LM32_INT_REG_R8,
LM32_INT_REG_R9, LM32_INT_REG_R10, LM32_INT_REG_RA, LM32_INT_REG_EA,
LM32_INT_REG_BA, LM32_INT_REG_R11, LM32_INT_REG_R12, LM32_INT_REG_R13,
LM32_INT_REG_R14, LM32_INT_REG_R15, LM32_INT_REG_R16, LM32_INT_REG_R17,
LM32_INT_REG_R18, LM32_INT_REG_R19, LM32_INT_REG_R20, LM32_INT_REG_R21,
LM32_INT_REG_R22, LM32_INT_REG_R23, LM32_INT_REG_R24, LM32_INT_REG_R25,
LM32_INT_REG_GP, LM32_INT_REG_FP, LM32_INT_REG_SP, LM32_INT_REG_PC,
LM32_INT_REG_EID, LM32_INT_REG_EBA, LM32_INT_REG_DEBA, LM32_INT_REG_IE,
};
#endif /* _GDB_IF_H */
/** @} */

View File

@@ -1,338 +0,0 @@
/*
* lm32 debug exception vectors
*
* Michael Walle <michael@walle.cc>, 2009
*
* If debugging is enabled the debug exception base address (deba) gets
* remapped to this file.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
*/
#include "bspopts.h"
.section .text
/* (D)EBA alignment */
.align 256
.globl _deba
_deba:
debug_reset_handler:
/* Clear r0 */
xor r0,r0,r0
/* Disable interrupts */
wcsr IE, r0
/* Mask all interrupts */
wcsr IM,r0
/* Jump to original crt0 */
.extern crt0
mvhi r1, hi(crt0)
ori r1, r1, lo(crt0)
b r1
nop
nop
debug_breakpoint_handler:
/* Clear r0 in case it was corrupted */
xor r0, r0, r0
mvhi r0, hi(registers)
ori r0, r0, lo(registers)
sw (r0+116), ra
sw (r0+128), ba
calli save_all
calli handle_exception
calli b_restore_and_return
debug_instruction_bus_error_handler:
/* Clear r0 in case it was corrupted */
xor r0, r0, r0
mvhi r0, hi(registers)
ori r0, r0, lo(registers)
sw (r0+116), ra
sw (r0+128), ea
calli save_all
calli handle_exception
calli e_restore_and_return
debug_watchpoint_handler:
/* Clear r0 in case it was corrupted */
xor r0, r0, r0
mvhi r0, hi(registers)
ori r0, r0, lo(registers)
sw (r0+116), ra
sw (r0+128), ba
calli save_all
calli handle_exception
calli b_restore_and_return
debug_data_bus_error_handler:
/* Clear r0 in case it was corrupted */
xor r0, r0, r0
mvhi r0, hi(registers)
ori r0, r0, lo(registers)
sw (r0+116), ra
sw (r0+128), ea
calli save_all
calli handle_exception
calli e_restore_and_return
debug_divide_by_zero_handler:
/* Clear r0 in case it was corrupted */
xor r0, r0, r0
mvhi r0, hi(registers)
ori r0, r0, lo(registers)
sw (r0+116), ra
sw (r0+128), ea
calli save_all
calli handle_exception
calli e_restore_and_return
debug_interrupt_handler:
bi debug_isr_handler
nop
nop
nop
nop
nop
nop
nop
debug_system_call_handler:
/* Clear r0 in case it was corrupted */
xor r0, r0, r0
mvhi r0, hi(registers)
ori r0, r0, lo(registers)
sw (r0+116), ra
sw (r0+128), ea
calli save_all
calli handle_exception
calli e_restore_and_return
debug_isr_handler:
addi sp, sp, -156
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
sw (sp+16), r4
sw (sp+20), r5
sw (sp+24), r6
sw (sp+28), r7
sw (sp+32), r8
sw (sp+36), r9
sw (sp+40), r10
sw (sp+44), ra
sw (sp+48), ea
sw (sp+52), ba
sw (sp+56), r11
sw (sp+60), r12
sw (sp+64), r13
sw (sp+68), r14
sw (sp+72), r15
sw (sp+76), r16
sw (sp+80), r17
sw (sp+84), r18
sw (sp+88), r19
sw (sp+92), r20
sw (sp+96), r21
sw (sp+100), r22
sw (sp+104), r23
sw (sp+108), r24
sw (sp+112), r25
sw (sp+116), r26
sw (sp+120), r27
/* 124 - SP */
addi r1, sp, 156
sw (sp+124), r1
/* 128 - PC */
sw (sp+128), ea
/* 132 - EID */
mvi r1, 6
sw (sp+132), r1
rcsr r1, EBA
sw (sp+136), r1
rcsr r1, DEBA
sw (sp+140), r1
rcsr r1, IE
sw (sp+144), r1
/* This is the same code as in cpu_asm.S */
rcsr r2, IP
rcsr r3, IM
mv r1, r0
and r2, r2, r3
mvi r3, 1
be r2, r0, 3f
1:
and r4, r2, r3
bne r4, r0, 2f
sli r3, r3, 1
addi r1, r1, 1
bi 1b
2:
addi r2, sp, 4
.extern __ISR_Handler
mvhi r3, hi(__ISR_Handler)
ori r3, r3, lo(__ISR_Handler)
call r3
3:
lw r1, (sp+4)
lw r2, (sp+8)
lw r3, (sp+12)
lw r4, (sp+16)
lw r5, (sp+20)
lw r6, (sp+24)
lw r7, (sp+28)
lw r8, (sp+32)
lw r9, (sp+36)
lw r10, (sp+40)
lw ra, (sp+44)
lw ea, (sp+48)
lw ba, (sp+52)
lw r11, (sp+56)
lw r12, (sp+60)
lw r13, (sp+64)
lw r14, (sp+68)
lw r15, (sp+72)
lw r16, (sp+76)
lw r17, (sp+80)
lw r18, (sp+84)
lw r19, (sp+88)
lw r20, (sp+92)
lw r21, (sp+96)
lw r22, (sp+100)
lw r23, (sp+104)
lw r24, (sp+108)
lw r25, (sp+112)
lw r26, (sp+116)
lw r27, (sp+120)
lw ea, (sp+136)
wcsr EBA, ea
lw ea, (sp+140)
wcsr DEBA, ea
/* Restore EA from PC */
lw ea, (sp+128)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+124)
eret
save_all:
sw (r0+4), r1
sw (r0+8), r2
sw (r0+12), r3
sw (r0+16), r4
sw (r0+20), r5
sw (r0+24), r6
sw (r0+28), r7
sw (r0+32), r8
sw (r0+36), r9
sw (r0+40), r10
sw (r0+44), r11
sw (r0+48), r12
sw (r0+52), r13
sw (r0+56), r14
sw (r0+60), r15
sw (r0+64), r16
sw (r0+68), r17
sw (r0+72), r18
sw (r0+76), r19
sw (r0+80), r20
sw (r0+84), r21
sw (r0+88), r22
sw (r0+92), r23
sw (r0+96), r24
sw (r0+100), r25
sw (r0+104), r26
sw (r0+108), r27
sw (r0+112), sp
/* 116 - RA - saved in handler code above */
sw (r0+120), ea
sw (r0+124), ba
/* 128 - PC - saved in handler code above */
/* 132 - EID - saved below */
rcsr r1, EBA
sw (r0+136), r1
rcsr r1, DEBA
sw (r0+140), r1
rcsr r1, IE
sw (r0+144), r1
/* Work out EID from exception entry point address */
andi r1, ra, 0xff
srui r1, r1, 5
sw (r0+132), r1
/* Save pointer to registers */
mv r1, r0
/* Restore r0 to 0 */
xor r0, r0, r0
/* Save r0 (hardcoded to 0) */
sw (r1+0), r0
ret
/* Restore gp registers */
restore_gp:
lw r1, (r0+4)
lw r2, (r0+8)
lw r3, (r0+12)
lw r4, (r0+16)
lw r5, (r0+20)
lw r6, (r0+24)
lw r7, (r0+28)
lw r8, (r0+32)
lw r9, (r0+36)
lw r10, (r0+40)
lw r11, (r0+44)
lw r12, (r0+48)
lw r13, (r0+52)
lw r14, (r0+56)
lw r15, (r0+60)
lw r16, (r0+64)
lw r17, (r0+68)
lw r18, (r0+72)
lw r19, (r0+76)
lw r20, (r0+80)
lw r21, (r0+84)
lw r22, (r0+88)
lw r23, (r0+92)
lw r24, (r0+96)
lw r25, (r0+100)
lw r26, (r0+104)
lw r27, (r0+108)
ret
/* Restore registers and return from exception */
e_restore_and_return:
/* first restore gp registers */
mvhi r0, hi(registers)
ori r0, r0, lo(registers)
calli restore_gp
lw sp, (r0+112)
lw ra, (r0+116)
lw ba, (r0+124)
lw ea, (r0+136)
wcsr EBA, ea
lw ea, (r0+140)
wcsr DEBA, ea
/* Restore EA from PC */
lw ea, (r0+128)
xor r0, r0, r0
eret
/* Restore registers and return from breakpoint */
b_restore_and_return:
/* first restore gp registers */
mvhi r0, hi(registers)
ori r0, r0, lo(registers)
calli restore_gp
lw sp, (r0+112)
lw ra, (r0+116)
lw ea, (r0+120)
lw ba, (r0+136)
wcsr EBA, ba
lw ba, (r0+140)
wcsr DEBA, ba
/* Restore BA from PC */
lw ba, (r0+128)
xor r0, r0, r0
bret

View File

@@ -1,977 +0,0 @@
/*
* Low-level support for LM32 remote debuging with GDB.
* Contributed by Jon Beniston <jon@beniston.com>
* Modified for RTEMS with thread support by Michael Walle <michael@walle.cc>
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*/
#include <bsp.h>
#include <string.h>
#include <signal.h>
#include <rtems.h>
#include <rtems/score/cpu.h>
#include "gdb_if.h"
/* Enable support for run-length encoding */
#undef GDB_RLE_ENABLED
/* Enable support for restart packets */
#undef GDB_RESTART_ENABLED
#define GDB_STUB_ENABLE_THREAD_SUPPORT
/*
* The following external functions provide character input and output.
*/
extern char gdb_get_debug_char(void);
extern void gdb_put_debug_char(char);
extern void gdb_console_init(void);
extern void gdb_ack_irq(void);
extern void *_deba;
/* Function prototypes */
static void allow_nested_exception(void);
static void disallow_nested_exception(void);
static char *mem2hex(unsigned char *mem, char *buf, int count);
static unsigned char *hex2mem(char *buf, unsigned char *mem, int count);
static unsigned char *bin2mem(char *buf, unsigned char *mem, int count);
static int compute_signal(int eid);
static void flush_cache(void);
static int hex2int(char **ptr, int *int_value);
static char *getpacket(void);
static void putpacket(char *buffer);
unsigned int registers[NUM_REGS];
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers */
#define BUFMAX 1500
/* I/O packet buffers */
static char remcomInBuffer[BUFMAX];
static char remcomOutBuffer[BUFMAX];
/*
* Set by debugger to indicate that when handling memory faults (bus errors), the
* handler should set the mem_err flag and skip over the faulting instruction
*/
static volatile int may_fault;
/*
* Set by bus error exception handler, this indicates to caller of mem2hex,
* hex2mem or bin2mem that there has been an error.
*/
static volatile int mem_err;
/* Indicates if we're single stepping */
static unsigned char stepping;
static char branch_step;
/* Saved instructions */
static unsigned int *seq_ptr;
static unsigned int seq_insn;
static unsigned int *branch_ptr;
static unsigned int branch_insn;
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
static char do_threads;
int current_thread_registers[NUM_REGS];
#endif
/* this mapping is used to copy the registers from a debug interrupt frame
* see gdb_handle_break() */
static unsigned char reg_map[] = {
0, LM32_INT_REG_R1, LM32_INT_REG_R2, LM32_INT_REG_R3, LM32_INT_REG_R4,
LM32_INT_REG_R5, LM32_INT_REG_R6, LM32_INT_REG_R7, LM32_INT_REG_R8,
LM32_INT_REG_R9, LM32_INT_REG_R10, LM32_INT_REG_R11, LM32_INT_REG_R12,
LM32_INT_REG_R13, LM32_INT_REG_R14, LM32_INT_REG_R15, LM32_INT_REG_R16,
LM32_INT_REG_R17, LM32_INT_REG_R18, LM32_INT_REG_R19, LM32_INT_REG_R20,
LM32_INT_REG_R21, LM32_INT_REG_R22, LM32_INT_REG_R23, LM32_INT_REG_R24,
LM32_INT_REG_R25, LM32_INT_REG_GP, LM32_INT_REG_FP, LM32_INT_REG_SP,
LM32_INT_REG_RA, LM32_INT_REG_EA, LM32_INT_REG_BA, LM32_INT_REG_PC,
LM32_INT_REG_EID, LM32_INT_REG_EBA, LM32_INT_REG_DEBA, LM32_INT_REG_IE
};
/*
* Conversion helper functions
*/
/* For integer to ASCII conversion */
#define highhex(x) gdb_hexchars [(x >> 4) & 0xf]
#define lowhex(x) gdb_hexchars [x & 0xf]
const char gdb_hexchars[]="0123456789abcdef";
/* Convert ch from a hex digit to an int */
static int hex(
unsigned char ch
)
{
if (ch >= 'a' && ch <= 'f')
return ch-'a'+10;
if (ch >= '0' && ch <= '9')
return ch-'0';
if (ch >= 'A' && ch <= 'F')
return ch-'A'+10;
return -1;
}
/*
* Convert the memory pointed to by mem into hex, placing result in buf.
* Return a pointer to the last char put in buf ('\0'), in case of mem fault,
* return NULL.
*/
static char *mem2hex(
unsigned char *mem,
char *buf, int count
)
{
unsigned char ch;
while (count-- > 0)
{
ch = *mem++;
if (mem_err)
return NULL;
*buf++ = highhex(ch);
*buf++ = lowhex(ch);
}
*buf = '\0';
return buf;
}
/*
* Convert the hex array pointed to by buf into binary to be placed in mem.
* Return a pointer to the character AFTER the last byte written.
*/
static unsigned char *hex2mem(
char *buf,
unsigned char *mem,
int count
)
{
int i;
unsigned char ch;
for (i = 0; i < count; i++)
{
/* Convert hex data to 8-bit value */
ch = hex(*buf++) << 4;
ch |= hex(*buf++);
/* Attempt to write data to memory */
*mem++ = ch;
/* Return NULL if write caused an exception */
if (mem_err)
return NULL;
}
return mem;
}
/*
* Copy the binary data pointed to by buf to mem and return a pointer to the
* character AFTER the last byte written $, # and 0x7d are escaped with 0x7d.
*/
static unsigned char *bin2mem(
char *buf,
unsigned char *mem,
int count
)
{
int i;
unsigned char c;
for (i = 0; i < count; i++)
{
/* Convert binary data to unsigned byte */
c = *buf++;
if (c == 0x7d)
c = *buf++ ^ 0x20;
/* Attempt to write value to memory */
*mem++ = c;
/* Return NULL if write caused an exception */
if (mem_err)
return NULL;
}
return mem;
}
/*
* While we find nice hex chars, build an int.
* Return number of chars processed.
*/
static int hex2int(
char **ptr,
int *int_value
)
{
int num_chars = 0;
int hex_value;
*int_value = 0;
while(**ptr)
{
hex_value = hex(**ptr);
if (hex_value < 0)
break;
*int_value = (*int_value << 4) | hex_value;
num_chars ++;
(*ptr)++;
}
return (num_chars);
}
/* Convert the exception identifier to a signal number. */
static int compute_signal(
int eid
)
{
switch (eid)
{
case LM32_EXCEPTION_RESET:
return 0;
case LM32_EXCEPTION_INTERRUPT:
return SIGINT;
case LM32_EXCEPTION_DATA_BREAKPOINT:
case LM32_EXCEPTION_INST_BREAKPOINT:
return SIGTRAP;
case LM32_EXCEPTION_INST_BUS_ERROR:
case LM32_EXCEPTION_DATA_BUS_ERROR:
return SIGSEGV;
case LM32_EXCEPTION_DIVIDE_BY_ZERO:
return SIGFPE;
}
return SIGHUP; /* default for things we don't know about */
}
/* Scan for the sequence $<data>#<checksum> */
static char *getpacket(void)
{
char *buffer = &remcomInBuffer[0];
unsigned char checksum;
unsigned char xmitcsum;
int count;
char ch;
while (1)
{
/* wait around for the start character, ignore all other characters */
while ((ch = gdb_get_debug_char()) != '$');
retry:
checksum = 0;
xmitcsum = -1;
count = 0;
/* now, read until a # or end of buffer is found */
while (count < BUFMAX)
{
ch = gdb_get_debug_char();
if (ch == '$')
goto retry;
if (ch == '#')
break;
checksum = checksum + ch;
buffer[count] = ch;
count = count + 1;
}
buffer[count] = 0;
if (ch == '#')
{
ch = gdb_get_debug_char();
xmitcsum = hex(ch) << 4;
ch = gdb_get_debug_char();
xmitcsum += hex(ch);
if (checksum != xmitcsum)
{
/* failed checksum */
gdb_put_debug_char('-');
}
else
{
/* successful transfer */
gdb_put_debug_char('+');
/* if a sequence char is present, reply the sequence ID */
if (buffer[2] == ':')
{
gdb_put_debug_char(buffer[0]);
gdb_put_debug_char(buffer[1]);
return &buffer[3];
}
return &buffer[0];
}
}
}
}
/* Send the packet in buffer. */
static void putpacket(
char *buffer
)
{
unsigned char checksum;
int count;
unsigned char ch;
#ifdef GDB_RLE_ENABLED
int run_length;
int run_idx;
char run_length_char;
#endif
/* $<packet info>#<checksum>. */
do {
gdb_put_debug_char('$');
checksum = 0;
count = 0;
#ifdef GDB_RLE_ENABLED
while (ch = buffer[count])
{
/* Transmit character */
gdb_put_debug_char(ch);
checksum += ch;
count += 1;
/*
* Determine how many consecutive characters there are that are the same
* as the character we just transmitted
*/
run_length = 0;
run_idx = count;
while ((buffer[run_idx++] == ch) && (run_length < 97))
run_length++;
/* Encode run length as an ASCII character */
run_length_char = (char)(run_length + 29);
if ( (run_length >= 3)
&& (run_length_char != '$')
&& (run_length_char != '#')
&& (run_length_char != '+')
&& (run_length_char != '-')
)
{
/* Transmit run-length */
gdb_put_debug_char('*');
checksum += '*';
gdb_put_debug_char(run_length_char);
checksum += run_length_char;
count += run_length;
}
}
#else
while ((ch = buffer[count]))
{
gdb_put_debug_char(ch);
checksum += ch;
count += 1;
}
#endif
gdb_put_debug_char('#');
gdb_put_debug_char(highhex(checksum));
gdb_put_debug_char(lowhex(checksum));
} while (gdb_get_debug_char() != '+');
}
static void allow_nested_exception(void)
{
mem_err = 0;
may_fault = 1;
}
static void disallow_nested_exception(void)
{
mem_err = 0;
may_fault = 0;
}
/* Flush the instruction cache */
static void flush_cache(void)
{
/*
* Executing this does no harm on CPUs without a cache. We flush data cache as
* well as instruction cache in case the debugger has accessed memory
* directly.
*/
__asm__ __volatile__ ("wcsr ICC, r0\n"
"nop\n"
"nop\n"
"nop\n"
"wcsr DCC, r0\n"
"nop\n"
"nop\n"
"nop"
);
}
/* Set a h/w breakpoint at the given address */
static int set_hw_breakpoint(
int address,
int length
)
{
int bp;
/* Find a free break point register and then set it */
__asm__ ("rcsr %0, BP0" : "=r" (bp));
if ((bp & 0x01) == 0)
{
__asm__ ("wcsr BP0, %0" : : "r" (address | 1));
return 1;
}
__asm__ ("rcsr %0, BP1" : "=r" (bp));
if ((bp & 0x01) == 0)
{
__asm__ ("wcsr BP1, %0" : : "r" (address | 1));
return 1;
}
__asm__ ("rcsr %0, BP2" : "=r" (bp));
if ((bp & 0x01) == 0)
{
__asm__ ("wcsr BP2, %0" : : "r" (address | 1));
return 1;
}
__asm__ ("rcsr %0, BP3" : "=r" (bp));
if ((bp & 0x01) == 0)
{
__asm__ ("wcsr BP3, %0" : : "r" (address | 1));
return 1;
}
/* No free breakpoint registers */
return -1;
}
/* Remove a h/w breakpoint which should be set at the given address */
static int disable_hw_breakpoint(
int address,
int length
)
{
int bp;
/* Try to find matching breakpoint register */
__asm__ ("rcsr %0, BP0" : "=r" (bp));
if ((bp & 0xfffffffc) == (address & 0xfffffffc))
{
__asm__ ("wcsr BP0, %0" : : "r" (0));
return 1;
}
__asm__ ("rcsr %0, BP1" : "=r" (bp));
if ((bp & 0xfffffffc) == (address & 0xfffffffc))
{
__asm__ ("wcsr BP1, %0" : : "r" (0));
return 1;
}
__asm__ ("rcsr %0, BP2" : "=r" (bp));
if ((bp & 0xfffffffc) == (address & 0xfffffffc))
{
__asm__ ("wcsr BP2, %0" : : "r" (0));
return 1;
}
__asm__ ("rcsr %0, BP3" : "=r" (bp));
if ((bp & 0xfffffffc) == (address & 0xfffffffc))
{
__asm__ ("wcsr BP3, %0" : : "r" (0));
return 1;
}
/* Breakpoint not found */
return -1;
}
/*
* This support function prepares and sends the message containing the
* basic information about this exception.
*/
static void gdb_stub_report_exception_info(
int thread
)
{
char *ptr;
int sigval;
/* Convert exception ID to a signal number */
sigval = compute_signal(registers[LM32_REG_EID]);
/* Set pointer to start of output buffer */
ptr = remcomOutBuffer;
*ptr++ = 'T';
*ptr++ = highhex(sigval);
*ptr++ = lowhex(sigval);
*ptr++ = highhex(LM32_REG_PC);
*ptr++ = lowhex(LM32_REG_PC);
*ptr++ = ':';
ptr = mem2hex((unsigned char *)&(registers[LM32_REG_PC]), ptr, 4);
*ptr++ = ';';
*ptr++ = highhex(LM32_REG_SP);
*ptr++ = lowhex(LM32_REG_SP);
*ptr++ = ':';
ptr = mem2hex((unsigned char *)&(registers[LM32_REG_SP]), ptr, 4);
*ptr++ = ';';
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
if (do_threads)
{
*ptr++ = 't';
*ptr++ = 'h';
*ptr++ = 'r';
*ptr++ = 'e';
*ptr++ = 'a';
*ptr++ = 'd';
*ptr++ = ':';
ptr = thread2vhstr(ptr, thread);
*ptr++ = ';';
}
#endif
*ptr++ = '\0';
}
/*
* This function does all command procesing for interfacing to gdb. The error
* codes we return are errno numbers.
*/
void handle_exception(void)
{
int addr;
int length;
char *ptr;
int err;
int reg;
unsigned insn;
unsigned opcode;
unsigned branch_target = 0;
int current_thread;
int thread;
void *regptr;
int host_has_detached = 0;
int binary;
thread = 0;
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
if (do_threads)
thread = rtems_gdb_stub_get_current_thread();
#endif
current_thread = thread;
/*
* Check for bus error caused by this code (rather than the program being
* debugged)
*/
if (may_fault && (registers[LM32_REG_EID] == LM32_EXCEPTION_DATA_BUS_ERROR))
{
/* Indicate that a fault occured */
mem_err = 1;
/* Skip over faulting instruction */
registers[LM32_REG_PC] += 4;
/* Resume execution */
return;
}
if (stepping)
{
/* Remove breakpoints */
*seq_ptr = seq_insn;
if (branch_step)
*branch_ptr = branch_insn;
stepping = 0;
}
/* Reply to host that an exception has occured with some basic info */
gdb_stub_report_exception_info(thread);
putpacket(remcomOutBuffer);
while (!host_has_detached)
{
remcomOutBuffer[0] = '\0';
ptr = getpacket();
binary = 0;
switch (*ptr++)
{
/* Return last signal */
case '?':
gdb_stub_report_exception_info(thread);
break;
/* Detach - exit from debugger */
case 'D':
strcpy(remcomOutBuffer, "OK");
host_has_detached = 1;
break;
/* Return the value of the CPU registers */
case 'g':
regptr = registers;
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
if (do_threads && current_thread != thread )
regptr = &current_thread_registers;
#endif
ptr = mem2hex((unsigned char*)regptr, remcomOutBuffer, NUM_REGS * 4);
break;
/* Set the value of the CPU registers */
case 'G':
regptr = registers;
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
if (do_threads && current_thread != thread )
regptr = &current_thread_registers;
#endif
hex2mem(ptr, (unsigned char*)regptr, NUM_REGS * 4);
strcpy(remcomOutBuffer, "OK");
break;
/* Return the value of the specified register */
case 'p':
if (hex2int(&ptr, &reg))
{
ptr = remcomOutBuffer;
ptr = mem2hex((unsigned char *)&registers[reg], ptr, 4);
} else
strcpy(remcomOutBuffer, "E22");
break;
/* Set the specified register to the given value */
case 'P':
if (hex2int(&ptr, &reg)
&& *ptr++ == '=')
{
hex2mem(ptr, (unsigned char *)&registers[reg], 4);
strcpy(remcomOutBuffer, "OK");
}
else
strcpy(remcomOutBuffer, "E22");
break;
/* Read memory */
case 'm':
/* Try to read %x,%x. */
if (hex2int(&ptr, &addr)
&& *ptr++ == ','
&& hex2int(&ptr, &length)
&& length < (sizeof(remcomOutBuffer)/2))
{
allow_nested_exception();
if (NULL == mem2hex((unsigned char *)addr, remcomOutBuffer, length))
strcpy(remcomOutBuffer, "E14");
disallow_nested_exception();
}
else
strcpy(remcomOutBuffer,"E22");
break;
/* Write memory */
case 'X':
binary = 1;
case 'M':
/* Try to read '%x,%x:'. */
if (hex2int(&ptr, &addr)
&& *ptr++ == ','
&& hex2int(&ptr, &length)
&& *ptr++ == ':')
{
allow_nested_exception();
if (binary)
err = (int)bin2mem(ptr, (unsigned char *)addr, length);
else
err = (int)hex2mem(ptr, (unsigned char *)addr, length);
if (err)
strcpy(remcomOutBuffer, "OK");
else
strcpy(remcomOutBuffer, "E14");
disallow_nested_exception();
}
else
strcpy(remcomOutBuffer, "E22");
break;
/* Continue */
case 'c':
/* try to read optional parameter, pc unchanged if no parm */
if (hex2int(&ptr, &addr))
registers[LM32_REG_PC] = addr;
flush_cache();
return;
/* Step */
case 's':
/* try to read optional parameter, pc unchanged if no parm */
if (hex2int(&ptr, &addr))
registers[LM32_REG_PC] = addr;
stepping = 1;
/* Is instruction a branch? */
insn = *(unsigned int*)registers[LM32_REG_PC];
opcode = insn & 0xfc000000;
if ( (opcode == 0xe0000000)
|| (opcode == 0xf8000000)
)
{
branch_step = 1;
branch_target = registers[LM32_REG_PC]
+ (((signed)insn << 6) >> 4);
}
else if ( (opcode == 0x44000000)
|| (opcode == 0x48000000)
|| (opcode == 0x4c000000)
|| (opcode == 0x50000000)
|| (opcode == 0x54000000)
|| (opcode == 0x5c000000)
)
{
branch_step = 1;
branch_target = registers[LM32_REG_PC] +
+ (((signed)insn << 16) >> 14);
}
else if ( (opcode == 0xd8000000)
|| (opcode == 0xc0000000)
)
{
branch_step = 1;
branch_target = registers[(insn >> 21) & 0x1f];
}
else
branch_step = 0;
/* Set breakpoint after instruction we're stepping */
seq_ptr = (unsigned int *)registers[LM32_REG_PC];
seq_ptr++;
seq_insn = *seq_ptr;
*seq_ptr = LM32_BREAK;
/* Make sure one insn doesn't get replaced twice */
if (seq_ptr == (unsigned int*)branch_target)
branch_step = 0;
if (branch_step)
{
/* Set breakpoint on branch target */
branch_ptr = (unsigned int*)branch_target;
branch_insn = *branch_ptr;
*branch_ptr = LM32_BREAK;
}
flush_cache();
return;
case 'Z':
switch (*ptr++)
{
/* Insert h/w breakpoint */
case '1':
if (*ptr++ == ','
&& hex2int(&ptr, &addr)
&& *ptr++ == ','
&& hex2int(&ptr, &length))
{
err = set_hw_breakpoint(addr, length);
if (err > 0)
strcpy(remcomOutBuffer, "OK");
else if (err < 0)
strcpy(remcomOutBuffer, "E28");
}
else
strcpy(remcomOutBuffer, "E22");
break;
}
break;
case 'z':
switch (*ptr++)
{
/* Remove h/w breakpoint */
case '1':
if (*ptr++ == ','
&& hex2int(&ptr, &addr)
&& *ptr++ == ','
&& hex2int(&ptr, &length))
{
err = disable_hw_breakpoint(addr, length);
if (err > 0)
strcpy(remcomOutBuffer, "OK");
else if (err < 0)
strcpy(remcomOutBuffer, "E28");
}
else
strcpy(remcomOutBuffer, "E22");
break;
}
break;
/* Query */
case 'q':
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
rtems_gdb_process_query(
remcomInBuffer,
remcomOutBuffer,
do_threads,
thread );
#endif
break;
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
/* Thread alive */
case 'T':
{
int testThread;
if (vhstr2thread(&remcomInBuffer[1], &testThread) == NULL)
{
strcpy(remcomOutBuffer, "E01");
break;
}
if (rtems_gdb_index_to_stub_id(testThread) == NULL)
strcpy(remcomOutBuffer, "E02");
else
strcpy(remcomOutBuffer, "OK");
}
break;
#endif
/* Set thread */
case 'H':
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
if (remcomInBuffer[1] != 'g')
break;
if (!do_threads)
break;
{
int tmp, ret;
/* Set new generic thread */
if (vhstr2thread(&remcomInBuffer[2], &tmp) == NULL)
{
strcpy(remcomOutBuffer, "E01");
break;
}
/* 0 means `thread' */
if (tmp == 0)
tmp = thread;
if (tmp == current_thread)
{
/* No changes */
strcpy(remcomOutBuffer, "OK");
break;
}
/* Save current thread registers if necessary */
if (current_thread != thread)
{
ret = rtems_gdb_stub_set_thread_regs(
current_thread, (unsigned int *) &current_thread_registers);
}
/* Read new registers if necessary */
if (tmp != thread)
{
ret = rtems_gdb_stub_get_thread_regs(
tmp, (unsigned int *) &current_thread_registers);
if (!ret)
{
/* Thread does not exist */
strcpy(remcomOutBuffer, "E02");
break;
}
}
current_thread = tmp;
strcpy(remcomOutBuffer, "OK");
}
#endif
break;
#ifdef GDB_RESTART_ENABLED
/* Reset */
case 'r':
case 'R':
/* We reset by branching to the reset exception handler. */
registers[LM32_REG_PC] = 0;
return;
#endif
}
/* reply to the request */
putpacket(remcomOutBuffer);
}
}
void gdb_handle_break(rtems_vector_number vector, CPU_Interrupt_frame *frame)
{
int i;
unsigned int *int_regs = (unsigned int*)frame;
/* copy extended frame to registers */
registers[LM32_REG_R0] = 0;
for (i = 1; i < NUM_REGS; i++)
{
registers[i] = int_regs[reg_map[i]];
}
/* now call the real handler */
handle_exception();
gdb_ack_irq();
/* copy registers back to extended frame */
for (i = 1; i < NUM_REGS; i++)
{
int_regs[reg_map[i]] = registers[i];
}
}
void lm32_gdb_stub_install(int enable_threads)
{
unsigned int dc;
/* set DEBA and remap all exception */
__asm__("wcsr DEBA, %0" : : "r" (&_deba));
__asm__("rcsr %0, DC" : "=r" (dc));
dc |= 0x2;
__asm__("wcsr DC, %0" : : "r" (dc));
#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
if( enable_threads )
do_threads = 1;
else
do_threads = 0;
#endif
gdb_console_init();
}

View File

@@ -1,93 +0,0 @@
/* irq.c
*
* Copyright (c) 2010 Sebastien Bourdeauducq
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <bsp.h>
#include <rtems/score/cpu.h>
#include <bsp/irq.h>
#include <bsp/irq-generic.h>
void bsp_interrupt_facility_initialize(void)
{
/* Nothing to do */
}
rtems_status_code bsp_interrupt_get_attributes(
rtems_vector_number vector,
rtems_interrupt_attributes *attributes
)
{
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_is_pending(
rtems_vector_number vector,
bool *pending
)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
bsp_interrupt_assert(pending != NULL);
*pending = false;
return RTEMS_UNSATISFIED;
}
rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
return RTEMS_UNSATISFIED;
}
rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
return RTEMS_UNSATISFIED;
}
rtems_status_code bsp_interrupt_vector_is_enabled(
rtems_vector_number vector,
bool *enabled
)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
bsp_interrupt_assert(enabled != NULL);
*enabled = false;
return RTEMS_UNSATISFIED;
}
rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
lm32_interrupt_unmask(1 << vector);
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
lm32_interrupt_mask(1 << vector);
return RTEMS_SUCCESSFUL;
}
rtems_status_code bsp_interrupt_set_priority(
rtems_vector_number vector,
uint32_t priority
)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
return RTEMS_UNSATISFIED;
}
rtems_status_code bsp_interrupt_get_priority(
rtems_vector_number vector,
uint32_t *priority
)
{
bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
bsp_interrupt_assert(priority != NULL);
return RTEMS_UNSATISFIED;
}

View File

@@ -1,436 +0,0 @@
/* ac97.c
*
* Sound driver for Milkymist SoC
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/libio.h>
#include <rtems/status-checks.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_ac97.h>
#define SND_DEVICE_NAME "/dev/snd"
#define MIXER_DEVICE_NAME "/dev/mixer"
static rtems_id cr_write_sem;
static rtems_id cr_read_sem;
static rtems_isr crrequest_handler(rtems_vector_number n)
{
rtems_semaphore_release(cr_write_sem);
lm32_interrupt_ack(1 << MM_IRQ_AC97CRREQUEST);
}
static rtems_isr crreply_handler(rtems_vector_number n)
{
rtems_semaphore_release(cr_read_sem);
lm32_interrupt_ack(1 << MM_IRQ_AC97CRREPLY);
}
/* queued playback buffers */
#define PLAY_Q_SIZE 8
#define PLAY_Q_MASK (PLAY_Q_SIZE-1)
static struct snd_buffer *play_q[PLAY_Q_SIZE];
static int play_produce;
static int play_consume;
static int play_level;
/* buffers played, for application to collect */
static rtems_id play_q_done;
static void play_start(struct snd_buffer *buf)
{
if (buf->nsamples > (AC97_MAX_DMASIZE/4))
buf->nsamples = AC97_MAX_DMASIZE/4;
MM_WRITE(MM_AC97_DADDRESS, (unsigned int)buf->samples);
MM_WRITE(MM_AC97_DREMAINING, buf->nsamples*4);
MM_WRITE(MM_AC97_DCTL, AC97_SCTL_EN);
}
static rtems_isr pcmplay_handler(rtems_vector_number n)
{
lm32_interrupt_ack(1 << MM_IRQ_AC97DMAR);
rtems_message_queue_send(play_q_done, &play_q[play_consume],
sizeof(void *));
play_consume = (play_consume + 1) & PLAY_Q_MASK;
play_level--;
if(play_level > 0)
play_start(play_q[play_consume]);
else
MM_WRITE(MM_AC97_DCTL, 0);
}
/* queued record buffers */
#define RECORD_Q_SIZE 8
#define RECORD_Q_MASK (RECORD_Q_SIZE-1)
static struct snd_buffer *record_q[RECORD_Q_SIZE];
static int record_produce;
static int record_consume;
static int record_level;
/* buffers recorded, for application to collect */
static rtems_id record_q_done;
static void record_start(struct snd_buffer *buf)
{
if (buf->nsamples > (AC97_MAX_DMASIZE/4))
buf->nsamples = AC97_MAX_DMASIZE/4;
MM_WRITE(MM_AC97_UADDRESS, (unsigned int)buf->samples);
MM_WRITE(MM_AC97_UREMAINING, buf->nsamples*4);
MM_WRITE(MM_AC97_UCTL, AC97_SCTL_EN);
}
static rtems_isr pcmrecord_handler(rtems_vector_number n)
{
lm32_interrupt_ack(1 << MM_IRQ_AC97DMAW);
__asm__ volatile( /* Invalidate Level-1 data cache */
"wcsr DCC, r0\n"
"nop\n"
);
rtems_message_queue_send(record_q_done, &record_q[record_consume],
sizeof(void *));
record_consume = (record_consume + 1) & RECORD_Q_MASK;
record_level--;
if(record_level > 0)
record_start(record_q[record_consume]);
else
MM_WRITE(MM_AC97_UCTL, 0);
}
rtems_device_driver ac97_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
rtems_isr_entry dummy;
sc = rtems_io_register_name(SND_DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create snd device");
sc = rtems_io_register_name(MIXER_DEVICE_NAME, major, 1);
RTEMS_CHECK_SC(sc, "create mixer device");
sc = rtems_semaphore_create(
rtems_build_name('C', 'R', 'W', 'S'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE,
0,
&cr_write_sem
);
RTEMS_CHECK_SC(sc, "create AC97 register write semaphore");
sc = rtems_semaphore_create(
rtems_build_name('C', 'R', 'R', 'S'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE,
0,
&cr_read_sem
);
RTEMS_CHECK_SC(sc, "create AC97 register read semaphore");
sc = rtems_message_queue_create(
rtems_build_name('P', 'L', 'Y', 'Q'),
PLAY_Q_SIZE*2,
sizeof(void *),
0,
&play_q_done
);
RTEMS_CHECK_SC(sc, "create playback done queue");
sc = rtems_message_queue_create(
rtems_build_name('R', 'E', 'C', 'Q'),
RECORD_Q_SIZE*2,
sizeof(void *),
0,
&record_q_done
);
RTEMS_CHECK_SC(sc, "create record done queue");
rtems_interrupt_catch(crrequest_handler, MM_IRQ_AC97CRREQUEST, &dummy);
rtems_interrupt_catch(crreply_handler, MM_IRQ_AC97CRREPLY, &dummy);
rtems_interrupt_catch(pcmplay_handler, MM_IRQ_AC97DMAR, &dummy);
rtems_interrupt_catch(pcmrecord_handler, MM_IRQ_AC97DMAW, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_AC97CRREQUEST);
bsp_interrupt_vector_enable(MM_IRQ_AC97CRREPLY);
bsp_interrupt_vector_enable(MM_IRQ_AC97DMAR);
bsp_interrupt_vector_enable(MM_IRQ_AC97DMAW);
play_produce = 0;
play_consume = 0;
play_level = 0;
record_produce = 0;
record_consume = 0;
record_level = 0;
return RTEMS_SUCCESSFUL;
}
static rtems_status_code submit_play(struct snd_buffer *buf)
{
bsp_interrupt_vector_disable(MM_IRQ_AC97DMAR);
if (play_level == PLAY_Q_SIZE) {
bsp_interrupt_vector_enable(MM_IRQ_AC97DMAR);
return RTEMS_UNSATISFIED;
}
play_q[play_produce] = buf;
play_produce = (play_produce + 1) & PLAY_Q_MASK;
play_level++;
if (play_level == 1)
play_start(buf);
bsp_interrupt_vector_enable(MM_IRQ_AC97DMAR);
return RTEMS_SUCCESSFUL;
}
static rtems_status_code collect_play(struct snd_buffer **buf)
{
size_t s;
return rtems_message_queue_receive(
play_q_done,
buf,
&s,
RTEMS_WAIT,
RTEMS_NO_TIMEOUT
);
}
static rtems_status_code submit_record(struct snd_buffer *buf)
{
bsp_interrupt_vector_disable(MM_IRQ_AC97DMAW);
if (record_level == RECORD_Q_SIZE) {
bsp_interrupt_vector_enable(MM_IRQ_AC97DMAW);
return RTEMS_UNSATISFIED;
}
record_q[record_produce] = buf;
record_produce = (record_produce + 1) & RECORD_Q_MASK;
record_level++;
if (record_level == 1)
record_start(buf);
bsp_interrupt_vector_enable(MM_IRQ_AC97DMAW);
return RTEMS_SUCCESSFUL;
}
static rtems_status_code collect_record(struct snd_buffer **buf)
{
size_t s;
return rtems_message_queue_receive(
record_q_done,
buf,
&s,
RTEMS_WAIT,
RTEMS_NO_TIMEOUT
);
}
#define CR_TIMEOUT 10
static int read_cr(unsigned int adr)
{
rtems_status_code sc;
MM_WRITE(MM_AC97_CRADDR, adr);
MM_WRITE(MM_AC97_CRCTL, AC97_CRCTL_RQEN);
sc = rtems_semaphore_obtain(cr_write_sem, RTEMS_WAIT, CR_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
return -1;
sc = rtems_semaphore_obtain(cr_read_sem, RTEMS_WAIT, CR_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
return -1;
return MM_READ(MM_AC97_CRDATAIN);
}
static int write_cr(unsigned int adr, unsigned int val)
{
rtems_status_code sc;
MM_WRITE(MM_AC97_CRADDR, adr);
MM_WRITE(MM_AC97_CRDATAOUT, val);
MM_WRITE(MM_AC97_CRCTL, AC97_CRCTL_RQEN|AC97_CRCTL_WRITE);
sc = rtems_semaphore_obtain(cr_write_sem, RTEMS_WAIT, CR_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
return 0;
return 1;
}
rtems_device_driver ac97_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
int codec_id;
if (minor == 0) {
/* snd */
return RTEMS_SUCCESSFUL;
} else {
/* mixer */
codec_id = read_cr(0x00);
if ((codec_id != 0x0d50) && (codec_id != 0x6150)) {
printk("AC97 codec detection failed\n");
return RTEMS_UNSATISFIED;
}
write_cr(0x02, 0x0000); /* master volume */
write_cr(0x04, 0x0f0f); /* headphones volume */
write_cr(0x18, 0x0000); /* PCM out volume */
write_cr(0x1c, 0x0f0f); /* record gain */
write_cr(0x1a, 0x0505); /* record select: stereo mix */
return RTEMS_SUCCESSFUL;
}
}
static rtems_status_code ioctl_read_channel(void *buf,
unsigned int chan, int mono)
{
unsigned int *val = (unsigned int *)buf;
int mic_boost;
int codec;
int left, right;
codec = read_cr(chan);
if (codec < 0)
return RTEMS_UNSATISFIED;
if (codec & 0x8000) {
/* muted */
*val = 0;
return RTEMS_SUCCESSFUL;
}
if (mono) {
left = 100-(((codec & 0x1f) + 1)*100)/32;
mic_boost = (codec & (1 << 6)) >> 6;
*val = left | mic_boost << 8;
} else {
right = 100-(((codec & 0x1f) + 1)*100)/32;
left = 100-((((codec & 0x1f00) >> 8) + 1)*100)/32;
*val = left | (right << 8);
}
return RTEMS_SUCCESSFUL;
}
static rtems_status_code ioctl_write_channel(void *buf,
unsigned int chan, int mono)
{
unsigned int *val = (unsigned int *)buf;
int mic_boost;
int left, right;
int codec;
rtems_status_code sc;
left = *val & 0xff;
left = (left*32)/100 - 1;
if (left < 0)
left = 0;
if (mono) {
mic_boost = *val >> 8;
right = 31;
} else {
right = (*val >> 8) & 0xff;
right = (right*32)/100 - 1;
if (right < 0)
right = 0;
}
if ((left == 0) && (right == 0))
/* mute */
codec = 0x8000;
else
codec = (31-left) | ((31-right) << 8);
if (mono) {
if (mic_boost)
codec |= (1 << 6);
else
codec &= ~(1 << 6);
}
if (!write_cr(chan, codec))
sc = RTEMS_UNSATISFIED;
else
sc = RTEMS_SUCCESSFUL;
return sc;
}
rtems_device_driver ac97_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
rtems_status_code sc;
args->ioctl_return = -1;
if(minor == 0) {
/* dsp */
switch (args->command) {
case SOUND_SND_SUBMIT_PLAY:
return submit_play((struct snd_buffer *)args->buffer);
case SOUND_SND_COLLECT_PLAY:
return collect_play((struct snd_buffer **)args->buffer);
case SOUND_SND_SUBMIT_RECORD:
return submit_record((struct snd_buffer *)args->buffer);
case SOUND_SND_COLLECT_RECORD:
return collect_record((struct snd_buffer **)args->buffer);
default:
return RTEMS_UNSATISFIED;
}
} else {
/* mixer */
switch (args->command) {
case SOUND_MIXER_READ(SOUND_MIXER_MIC):
sc = ioctl_read_channel(args->buffer, 0x0e, 1);
if(sc == RTEMS_SUCCESSFUL)
args->ioctl_return = 0;
return sc;
case SOUND_MIXER_READ(SOUND_MIXER_LINE):
sc = ioctl_read_channel(args->buffer, 0x10, 0);
if(sc == RTEMS_SUCCESSFUL)
args->ioctl_return = 0;
return sc;
case SOUND_MIXER_WRITE(SOUND_MIXER_MIC):
sc = ioctl_write_channel(args->buffer, 0x0e, 1);
if(sc == RTEMS_SUCCESSFUL)
args->ioctl_return = 0;
return sc;
case SOUND_MIXER_WRITE(SOUND_MIXER_LINE):
sc = ioctl_write_channel(args->buffer, 0x10, 0);
if(sc == RTEMS_SUCCESSFUL)
args->ioctl_return = 0;
return sc;
default:
return RTEMS_UNSATISFIED;
}
}
}

View File

@@ -1,130 +0,0 @@
/* buttons.c
*
* Buttons driver for the Milkymist One board
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <rtems.h>
#include <rtems/status-checks.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/libio.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_buttons.h>
#define DEVICE_NAME "/dev/buttons"
static rtems_id event_q;
static void send_byte(char b)
{
rtems_message_queue_send(event_q, &b, 1);
}
static rtems_isr interrupt_handler(rtems_vector_number n)
{
static unsigned int previous_keys;
unsigned int keys, pushed_keys, released_keys;
keys = MM_READ(MM_GPIO_IN) & (GPIO_BTN1|GPIO_BTN2|GPIO_BTN3);
pushed_keys = keys & ~previous_keys;
released_keys = previous_keys & ~keys;
previous_keys = keys;
if(pushed_keys & GPIO_BTN1)
send_byte('A');
if(pushed_keys & GPIO_BTN2)
send_byte('B');
if(pushed_keys & GPIO_BTN3)
send_byte('C');
if(released_keys & GPIO_BTN1)
send_byte('a');
if(released_keys & GPIO_BTN2)
send_byte('b');
if(released_keys & GPIO_BTN3)
send_byte('c');
lm32_interrupt_ack(1 << MM_IRQ_GPIO);
}
rtems_device_driver buttons_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
rtems_isr_entry dummy;
sc = rtems_io_register_name(DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create buttons device");
sc = rtems_message_queue_create(
rtems_build_name('B', 'T', 'N', 'Q'),
24,
1,
0,
&event_q
);
RTEMS_CHECK_SC(sc, "create buttons event queue");
rtems_interrupt_catch(interrupt_handler, MM_IRQ_GPIO, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_GPIO);
MM_WRITE(MM_GPIO_INTEN, GPIO_BTN1|GPIO_BTN2|GPIO_BTN3);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver buttons_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
uint32_t count;
rtems_message_queue_flush(event_q, &count);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver buttons_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rtems_status_code sc;
if(rw_args->count < 1) {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
sc = rtems_message_queue_receive(
event_q,
rw_args->buffer,
(size_t *)&rw_args->bytes_moved,
RTEMS_WAIT,
RTEMS_NO_TIMEOUT
);
if(sc == RTEMS_SUCCESSFUL)
return RTEMS_SUCCESSFUL;
else {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
}

View File

@@ -1,46 +0,0 @@
/*
* Clock device driver for Lattice Mico32 (lm32).
*/
/*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
* Telecom SudParis
*/
#include <bsp.h>
#include <bsp/irq-generic.h>
#include "../include/system_conf.h"
#include "clock.h"
#include "bspopts.h"
#if ON_SIMULATOR
#define CLOCK_DRIVER_USE_FAST_IDLE 1
#endif
#define Clock_driver_support_at_tick(arg) \
do { \
lm32_interrupt_ack(1 << MM_IRQ_TIMER0); \
} while (0)
#define Clock_driver_support_install_isr(_new ) \
do { \
rtems_isr_entry _old; \
rtems_interrupt_catch(_new, MM_IRQ_TIMER0, &_old); \
} while (0)
static void Clock_driver_support_initialize_hardware(void)
{
MM_WRITE(MM_TIMER0_COMPARE,
(MM_READ(MM_FREQUENCY)/(1000000/rtems_configuration_get_microseconds_per_tick())));
MM_WRITE(MM_TIMER0_COUNTER, 0);
MM_WRITE(MM_TIMER0_CONTROL, TIMER_ENABLE | TIMER_AUTORESTART);
bsp_interrupt_vector_enable(MM_IRQ_TIMER0);
}
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
#include "../../../shared/dev/clock/clockimpl.h"

View File

@@ -1,22 +0,0 @@
/**
* @file
* @ingroup lm32_clock RTEMSBSPsLM32SharedMilkymistOne
* @brief LatticeMico32 Timer (Clock) definitions
*/
/*
* This file contains definitions for LatticeMico32 Timer (Clock)
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
* Telecom SudParis
*/
#ifndef _BSPCLOCK_H
#define _BSPCLOCK_H
#endif /* _BSPCLOCK_H */

View File

@@ -1,216 +0,0 @@
/*
* Console driver for Milkymist
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
#include <unistd.h>
#include <termios.h>
#include <rtems.h>
#include <rtems/bspIo.h>
#include <rtems/libio.h>
#include <rtems/console.h>
#include <rtems/termiostypes.h>
#include <bsp/irq-generic.h>
#include "../include/system_conf.h"
#include "uart.h"
BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write;
BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read;
static struct rtems_termios_tty *tty;
static int mmconsole_first_open(int major, int minor, void *arg)
{
tty = ((rtems_libio_open_close_args_t *) arg)->iop->data1;
return rtems_termios_set_initial_baud(tty, UART_BAUD_RATE);
}
static int mmconsole_last_close(int major, int minor, void *arg)
{
return 0;
}
static int mmconsole_set_attributes(int minor, const struct termios *t)
{
int baud;
switch (t->c_ospeed) {
case B0:
baud = 0;
break;
case B50:
baud = 50;
break;
case B75:
baud = 75;
break;
case B110:
baud = 110;
break;
case B134:
baud = 134;
break;
case B150:
baud = 150;
break;
case B200:
baud = 200;
break;
case B300:
baud = 300;
break;
case B600:
baud = 600;
break;
case B1200:
baud = 1200;
break;
case B1800:
baud = 1800;
break;
case B2400:
baud = 2400;
break;
case B4800:
baud = 4800;
break;
case B9600:
baud = 9600;
break;
case B19200:
baud = 19200;
break;
case B38400:
baud = 38400;
break;
case B57600:
baud = 57600;
break;
case B115200:
baud = 115200;
break;
case B230400:
baud = 230400;
break;
case B460800:
baud = 460800;
break;
default:
baud = -1;
break;
}
if (baud > 0)
MM_WRITE(MM_UART_DIV, MM_READ(MM_FREQUENCY)/baud/16);
return 0;
}
static ssize_t mmconsole_write(int minor, const char *buf, size_t n)
{
if (n > 0) {
MM_WRITE(MM_UART_RXTX, *buf);
}
return 0;
}
static rtems_isr mmconsole_interrupt(rtems_vector_number n)
{
char c;
while (MM_READ(MM_UART_STAT) & UART_STAT_RX_EVT) {
c = MM_READ(MM_UART_RXTX);
MM_WRITE(MM_UART_STAT, UART_STAT_RX_EVT);
rtems_termios_enqueue_raw_characters(tty, &c, 1);
}
if (MM_READ(MM_UART_STAT) & UART_STAT_TX_EVT) {
MM_WRITE(MM_UART_STAT, UART_STAT_TX_EVT);
rtems_termios_dequeue_characters(tty, 1);
}
lm32_interrupt_ack(1 << MM_IRQ_UART);
}
static const rtems_termios_callbacks mmconsole_callbacks = {
.firstOpen = mmconsole_first_open,
.lastClose = mmconsole_last_close,
.pollRead = NULL,
.write = mmconsole_write,
.setAttributes = mmconsole_set_attributes,
.stopRemoteTx = NULL,
.startRemoteTx = NULL,
.outputUsesInterrupts = TERMIOS_IRQ_DRIVEN
};
rtems_device_driver console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
rtems_isr_entry dummy;
rtems_termios_initialize();
status = rtems_io_register_name("/dev/console", major, 0);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred(status);
rtems_interrupt_catch(mmconsole_interrupt, MM_IRQ_UART, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_UART);
MM_WRITE(MM_UART_CTRL, UART_CTRL_RX_INT|UART_CTRL_TX_INT);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_open(major, minor, arg, &mmconsole_callbacks);
}
rtems_device_driver console_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_close(arg);
}
rtems_device_driver console_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_read(arg);
}
rtems_device_driver console_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_write(arg);
}
rtems_device_driver console_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_ioctl(arg);
}

View File

@@ -1,46 +0,0 @@
/*
* Driver for Milkymist UART
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
* COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
* Telecom SudParis
*/
#include <rtems.h>
#include <rtems/libio.h>
#include "../include/system_conf.h"
#include "uart.h"
void BSP_uart_init(int baud)
{
MM_WRITE(MM_UART_DIV, MM_READ(MM_FREQUENCY)/baud/16);
}
void BSP_uart_polled_write(char ch)
{
rtems_interrupt_level level;
rtems_interrupt_disable(level);
while(!(MM_READ(MM_UART_STAT) & UART_STAT_THRE));
MM_WRITE(MM_UART_RXTX, ch);
while(!(MM_READ(MM_UART_STAT) & UART_STAT_THRE));
rtems_interrupt_enable(level);
}
int BSP_uart_polled_read(void)
{
char r;
rtems_interrupt_level level;
rtems_interrupt_disable(level);
while(!(MM_READ(MM_UART_STAT) & UART_STAT_RX_EVT));
r = MM_READ(MM_UART_RXTX);
MM_WRITE(MM_UART_STAT, UART_STAT_RX_EVT);
rtems_interrupt_enable(level);
return r;
}

View File

@@ -1,22 +0,0 @@
/**
* @file
* @ingroup lm32_uart RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist UART definitions
*/
/*
* This file contains definitions for the Milkymist UART
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef _BSPUART_H
#define _BSPUART_H
void BSP_uart_init(int baud);
void BSP_uart_polled_write(char ch);
int BSP_uart_polled_read(void);
#endif /* _BSPUART_H */

View File

@@ -1,128 +0,0 @@
/* dmx.c
*
* Milkymist DMX512 driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <sys/types.h>
#include <rtems.h>
#include <rtems/status-checks.h>
#include <bsp.h>
#include <rtems/libio.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_dmx.h>
#define IN_DEVICE_NAME "/dev/dmx_in"
#define OUT_DEVICE_NAME "/dev/dmx_out"
rtems_device_driver dmx_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
sc = rtems_io_register_name(IN_DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create DMX input device");
sc = rtems_io_register_name(OUT_DEVICE_NAME, major, 1);
RTEMS_CHECK_SC(sc, "create DMX output device");
return RTEMS_SUCCESSFUL;
}
rtems_device_driver dmx_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
int len;
unsigned int i;
unsigned char *values = (unsigned char *)rw_args->buffer;
len = 512 - rw_args->offset;
if (len < 0) {
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
if (len > rw_args->count)
len = rw_args->count;
if (minor == 0) {
for (i=0;i<len;i++)
values[i] = MM_READ(MM_DMX_RX((unsigned int)rw_args->offset+i));
} else {
for (i=0;i<len;i++)
values[i] = MM_READ(MM_DMX_TX((unsigned int)rw_args->offset+i));
}
rw_args->bytes_moved = len;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver dmx_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
int len;
unsigned int i;
unsigned char *values = (unsigned char *)rw_args->buffer;
if (minor == 0) {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
len = 512 - rw_args->offset;
if (len < 0) {
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
if (len > rw_args->count)
len = rw_args->count;
for (i=0;i<len;i++)
MM_WRITE(MM_DMX_TX((unsigned int)rw_args->offset+i), values[i]);
rw_args->bytes_moved = len;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver dmx_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
switch (args->command) {
case DMX_SET_THRU:
args->ioctl_return = 0;
MM_WRITE(MM_DMX_THRU, (unsigned int)args->buffer);
return RTEMS_SUCCESSFUL;
case DMX_GET_THRU:
args->ioctl_return = 0;
*((unsigned int *)args->buffer) = MM_READ(MM_DMX_THRU);
return RTEMS_SUCCESSFUL;
default:
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
}
}

View File

@@ -1,193 +0,0 @@
/* flash.c
*
* Milkymist flash driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems.h>
#include <stdio.h>
#include <bsp.h>
#include <string.h>
#include <rtems/libio.h>
#include <rtems/status-checks.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_flash.h>
static struct flash_partition partitions[FLASH_PARTITION_COUNT]
= FLASH_PARTITIONS;
static rtems_id flash_lock;
rtems_device_driver flash_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
int i;
char devname[16];
for (i=0;i<FLASH_PARTITION_COUNT;i++) {
sprintf(devname, "/dev/flash%d", i+1);
sc = rtems_io_register_name(devname, major, i);
RTEMS_CHECK_SC(sc, "Create flash device");
}
sc = rtems_semaphore_create(
rtems_build_name('F', 'L', 'S', 'H'),
1,
RTEMS_SIMPLE_BINARY_SEMAPHORE,
0,
&flash_lock
);
RTEMS_CHECK_SC(sc, "create semaphore");
return RTEMS_SUCCESSFUL;
}
rtems_device_driver flash_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
void *startaddr;
int len;
if (minor >= FLASH_PARTITION_COUNT)
return RTEMS_UNSATISFIED;
startaddr = (void *)(partitions[minor].start_address
+ (unsigned int)rw_args->offset);
len = partitions[minor].length - rw_args->offset;
if (len > rw_args->count)
len = rw_args->count;
if (len <= 0) {
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
rtems_semaphore_obtain(flash_lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
memcpy(rw_args->buffer, startaddr, len);
rtems_semaphore_release(flash_lock);
rw_args->bytes_moved = len;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver flash_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
volatile unsigned short *startaddr;
unsigned short *srcdata;
int len;
int this_time;
int remaining;
int i;
if (minor >= FLASH_PARTITION_COUNT)
return RTEMS_UNSATISFIED;
startaddr = (unsigned short *)(partitions[minor].start_address
+ (unsigned int)rw_args->offset);
len = partitions[minor].length - rw_args->offset;
if (len > rw_args->count)
len = rw_args->count;
if (len <= 2) {
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
len /= 2;
srcdata = (unsigned short *)rw_args->buffer;
remaining = len;
rtems_semaphore_obtain(flash_lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
while (remaining > 0) {
this_time = remaining;
if (this_time > 256)
this_time = 256;
/* Issue "Buffered Programming Setup" command
* and wait for buffer available.
*/
do {
*startaddr = 0x00e8;
} while (!(*startaddr & 0x0080));
/* Load word count */
*startaddr = this_time-1;
/* Fill buffer */
for(i=0;i<this_time;i++)
startaddr[i] = srcdata[i];
/* Issue "Buffer Programming Confirm" command */
*startaddr = 0x00d0;
while (!(*startaddr & 0x0080)); /* read status register, wait for ready */
*startaddr = 0x0050; /* clear status register */
/* update state */
startaddr += this_time;
srcdata += this_time;
remaining -= this_time;
}
*startaddr = 0x00ff; /* back to read array mode */
rtems_semaphore_release(flash_lock);
rw_args->bytes_moved = 2*len;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver flash_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
unsigned int eraseaddr_i;
volatile unsigned short *eraseaddr;
if (minor >= FLASH_PARTITION_COUNT) {
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
}
switch (args->command) {
case FLASH_GET_SIZE:
*((unsigned int *)args->buffer) = partitions[minor].length;
break;
case FLASH_GET_BLOCKSIZE:
*((unsigned int *)args->buffer) = 128*1024;
break;
case FLASH_ERASE_BLOCK:
eraseaddr_i = (unsigned int)args->buffer;
if (eraseaddr_i >= partitions[minor].length) {
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
}
eraseaddr_i = eraseaddr_i + partitions[minor].start_address;
eraseaddr = (unsigned short *)eraseaddr_i;
rtems_semaphore_obtain(flash_lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
*eraseaddr = 0x0020; /* erase */
*eraseaddr = 0x00d0;
while(!(*eraseaddr & 0x0080)); /* read status register, wait for ready */
*eraseaddr = 0x0050; /* clear status register */
*eraseaddr = 0x00ff; /* back to read array mode */
rtems_semaphore_release(flash_lock);
break;
default:
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
}
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,251 +0,0 @@
/* framebuffer.c
*
* This file is the framebuffer driver for the Milkymist VGA IP-core
* This VGA Core is a part of Milkymist System-on-Chip
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
* Telecom SudParis
* Copyright (c) 2011 Sebastien Bourdeauducq
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <rtems.h>
#include <bsp.h>
#include "../include/system_conf.h"
#include <rtems/libio.h>
#include <rtems/fb.h>
#include <rtems/framebuffer.h>
#include <rtems/bspIo.h>
static unsigned short int framebufferA[1024*768]
__attribute__((aligned(32)));
static unsigned short int framebufferB[1024*768]
__attribute__((aligned(32)));
static unsigned short int framebufferC[1024*768]
__attribute__((aligned(32)));
static unsigned short int *frontbuffer;
static unsigned short int *backbuffer;
static unsigned short int *lastbuffer;
static struct fb_var_screeninfo fb_var = {
.xres = 640,
.yres = 480,
.bits_per_pixel = 16
};
static struct fb_fix_screeninfo fb_fix = {
.smem_len = 1024 * 768 * 2,
.type = FB_TYPE_VGA_PLANES,
.visual = FB_VISUAL_TRUECOLOR,
.line_length = 80
};
static int get_fix_screen_info( struct fb_fix_screeninfo *info )
{
*info = fb_fix;
return 0;
}
static int get_var_screen_info( struct fb_var_screeninfo *info )
{
*info = fb_var;
return 0;
}
static void init_buffers(void)
{
frontbuffer = framebufferA;
backbuffer = framebufferB;
lastbuffer = framebufferC;
}
static void swap_buffers(void)
{
unsigned short int *p;
/* Make sure last buffer swap has been executed */
while (MM_READ(MM_VGA_BASEADDRESS_ACT) != MM_READ(MM_VGA_BASEADDRESS));
p = frontbuffer;
frontbuffer = backbuffer;
backbuffer = lastbuffer;
lastbuffer = p;
fb_fix.smem_start = (volatile char *)backbuffer;
MM_WRITE(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
}
static void set_video_mode(int mode)
{
int hres, vres;
MM_WRITE(MM_VGA_RESET, VGA_RESET);
hres = vres = 0;
switch(mode) {
case 0: // 640x480, pixel clock: 25MHz
hres = 640;
vres = 480;
MM_WRITE(MM_VGA_HSYNC_START, 656);
MM_WRITE(MM_VGA_HSYNC_END, 752);
MM_WRITE(MM_VGA_HSCAN, 799);
MM_WRITE(MM_VGA_VSYNC_START, 492);
MM_WRITE(MM_VGA_VSYNC_END, 494);
MM_WRITE(MM_VGA_VSCAN, 524);
MM_WRITE(MM_VGA_CLKSEL, 0);
break;
case 1: // 800x600, pixel clock: 50MHz
hres = 800;
vres = 600;
MM_WRITE(MM_VGA_HSYNC_START, 848);
MM_WRITE(MM_VGA_HSYNC_END, 976);
MM_WRITE(MM_VGA_HSCAN, 1040);
MM_WRITE(MM_VGA_VSYNC_START, 636);
MM_WRITE(MM_VGA_VSYNC_END, 642);
MM_WRITE(MM_VGA_VSCAN, 665);
MM_WRITE(MM_VGA_CLKSEL, 1);
break;
case 2: // 1024x768, pixel clock: 65MHz
hres = 1024;
vres = 768;
MM_WRITE(MM_VGA_HSYNC_START, 1048);
MM_WRITE(MM_VGA_HSYNC_END, 1184);
MM_WRITE(MM_VGA_HSCAN, 1344);
MM_WRITE(MM_VGA_VSYNC_START, 772);
MM_WRITE(MM_VGA_VSYNC_END, 778);
MM_WRITE(MM_VGA_VSCAN, 807);
MM_WRITE(MM_VGA_CLKSEL, 2);
break;
}
if((hres != 0) && (vres != 0)) {
MM_WRITE(MM_VGA_HRES, hres);
MM_WRITE(MM_VGA_VRES, vres);
fb_var.xres = hres;
fb_var.yres = vres;
memset(framebufferA, 0, hres*vres*2);
memset(framebufferB, 0, hres*vres*2);
memset(framebufferC, 0, hres*vres*2);
MM_WRITE(MM_VGA_BURST_COUNT, hres*vres/16);
MM_WRITE(MM_VGA_RESET, 0);
} /* otherwise, leave the VGA controller in reset */
}
rtems_device_driver frame_buffer_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code status;
init_buffers();
fb_fix.smem_start = (volatile char *)frontbuffer;
MM_WRITE(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
status = rtems_io_register_name(FRAMEBUFFER_DEVICE_0_NAME, major, 0);
if (status != RTEMS_SUCCESSFUL) {
printk("Error registering frame buffer device!\n");
rtems_fatal_error_occurred( status );
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver frame_buffer_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
rtems_device_driver frame_buffer_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return RTEMS_SUCCESSFUL;
}
rtems_device_driver frame_buffer_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len)
? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
memcpy(rw_args->buffer, (const void *)(fb_fix.smem_start + rw_args->offset),
rw_args->bytes_moved);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver frame_buffer_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len)
? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
memcpy((void *)(fb_fix.smem_start + rw_args->offset), rw_args->buffer,
rw_args->bytes_moved);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver frame_buffer_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
switch (args->command) {
case FBIOGET_FSCREENINFO:
args->ioctl_return =
get_fix_screen_info((struct fb_fix_screeninfo *)args->buffer);
return RTEMS_SUCCESSFUL;
case FBIOGET_VSCREENINFO:
args->ioctl_return =
get_var_screen_info((struct fb_var_screeninfo *)args->buffer);
return RTEMS_SUCCESSFUL;
case FBIOSWAPBUFFERS:
swap_buffers();
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
case FBIOSETBUFFERMODE:
args->ioctl_return = 0;
switch ((unsigned int)args->buffer) {
case FB_SINGLE_BUFFERED:
init_buffers();
fb_fix.smem_start = (volatile char *)frontbuffer;
MM_WRITE(MM_VGA_BASEADDRESS, (unsigned int)frontbuffer);
return RTEMS_SUCCESSFUL;
case FB_TRIPLE_BUFFERED:
fb_fix.smem_start = (volatile char *)backbuffer;
return RTEMS_SUCCESSFUL;
default:
return RTEMS_UNSATISFIED;
}
case FBIOSETVIDEOMODE:
set_video_mode((int)args->buffer);
return RTEMS_SUCCESSFUL;
default:
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
}
}

View File

@@ -1,119 +0,0 @@
/* gpio.c
*
* GPIO driver for the Milkymist One board
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
* COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
* Telecom SudParis
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <rtems.h>
#include <rtems/status-checks.h>
#include <bsp.h>
#include <rtems/libio.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_gpio.h>
struct milkymist_gpio {
char *name;
unsigned int mask;
bool readonly;
};
static const struct milkymist_gpio gpio[] = {
{
.name = "/dev/led1",
.mask = GPIO_LED1,
.readonly = false
},
{
.name = "/dev/led2",
.mask = GPIO_LED2,
.readonly = false
},
};
rtems_device_driver gpio_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
int i;
for (i=0;i<sizeof(gpio)/sizeof(struct milkymist_gpio);i++) {
sc = rtems_io_register_name(gpio[i].name, major, i);
RTEMS_CHECK_SC(sc, "create GPIO device");
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver gpio_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
unsigned int data;
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
if (rw_args->offset > 0) {
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
rw_args->bytes_moved = 1;
if (gpio[minor].readonly)
data = MM_READ(MM_GPIO_IN);
else
data = MM_READ(MM_GPIO_OUT);
if (data & gpio[minor].mask)
*(uint8_t *)rw_args->buffer = '1';
else
*(uint8_t *)rw_args->buffer = '0';
return RTEMS_SUCCESSFUL;
}
rtems_device_driver gpio_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
if (gpio[minor].readonly) {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
if (rw_args->offset > 0) {
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
rw_args->bytes_moved = 1;
if (*(uint8_t *)rw_args->buffer == '1')
MM_WRITE(MM_GPIO_OUT, MM_READ(MM_GPIO_OUT)|gpio[minor].mask);
else
MM_WRITE(MM_GPIO_OUT, MM_READ(MM_GPIO_OUT) & ~gpio[minor].mask);
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,104 +0,0 @@
/* ir.c
*
* Milkymist RC5 IR driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <sys/types.h>
#include <rtems.h>
#include <rtems/status-checks.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/libio.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_ir.h>
#define DEVICE_NAME "/dev/ir"
static rtems_id ir_q;
static rtems_isr interrupt_handler(rtems_vector_number n)
{
unsigned short int msg;
lm32_interrupt_ack(1 << MM_IRQ_IR);
msg = MM_READ(MM_IR_RX);
rtems_message_queue_send(ir_q, &msg, 2);
}
rtems_device_driver ir_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
rtems_isr_entry dummy;
sc = rtems_io_register_name(DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create IR input device");
sc = rtems_message_queue_create(
rtems_build_name('R', 'C', '5', 'Q'),
64,
2,
0,
&ir_q
);
RTEMS_CHECK_SC(sc, "create IR queue");
rtems_interrupt_catch(interrupt_handler, MM_IRQ_IR, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_IR);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver ir_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
uint32_t count;
rtems_message_queue_flush(ir_q, &count);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver ir_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rtems_status_code sc;
if (rw_args->count < 2) {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
sc = rtems_message_queue_receive(
ir_q,
rw_args->buffer,
(size_t *)&rw_args->bytes_moved,
RTEMS_WAIT,
RTEMS_NO_TIMEOUT
);
if(sc == RTEMS_SUCCESSFUL)
return RTEMS_SUCCESSFUL;
else {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
}

View File

@@ -1,340 +0,0 @@
/* memcard.c
*
* Milkymist memory card driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <rtems.h>
#include <rtems/libio.h>
#include <rtems/blkdev.h>
#include <rtems/status-checks.h>
#include <errno.h>
#include <bsp.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_memcard.h>
//#define MEMCARD_DEBUG
#define BLOCK_SIZE 512
static void memcard_start_cmd_tx(void)
{
MM_WRITE(MM_MEMCARD_ENABLE, MEMCARD_ENABLE_CMD_TX);
}
static void memcard_start_cmd_rx(void)
{
MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_CMD_RX);
MM_WRITE(MM_MEMCARD_START, MEMCARD_START_CMD_RX);
MM_WRITE(MM_MEMCARD_ENABLE, MEMCARD_ENABLE_CMD_RX);
}
static void memcard_start_cmd_dat_rx(void)
{
MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_CMD_RX|MEMCARD_PENDING_DAT_RX);
MM_WRITE(MM_MEMCARD_START, MEMCARD_START_CMD_RX|MEMCARD_START_DAT_RX);
MM_WRITE(MM_MEMCARD_ENABLE, MEMCARD_ENABLE_CMD_RX|MEMCARD_ENABLE_DAT_RX);
}
static void memcard_send_command(unsigned char cmd, unsigned int arg)
{
unsigned char packet[6];
int a;
int i;
unsigned char data;
unsigned char crc;
packet[0] = cmd | 0x40;
packet[1] = ((arg >> 24) & 0xff);
packet[2] = ((arg >> 16) & 0xff);
packet[3] = ((arg >> 8) & 0xff);
packet[4] = (arg & 0xff);
crc = 0;
for(a=0;a<5;a++) {
data = packet[a];
for(i=0;i<8;i++) {
crc <<= 1;
if((data & 0x80) ^ (crc & 0x80))
crc ^= 0x09;
data <<= 1;
}
}
crc = (crc<<1) | 1;
packet[5] = crc;
#ifdef MEMCARD_DEBUG
printk(">> %02x %02x %02x %02x %02x %02x\n",
packet[0], packet[1], packet[2], packet[3], packet[4], packet[5]);
#endif
for(i=0;i<6;i++) {
MM_WRITE(MM_MEMCARD_CMD, packet[i]);
while(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_TX);
}
}
static void memcard_send_dummy(void)
{
MM_WRITE(MM_MEMCARD_CMD, 0xff);
while(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_TX);
}
static bool memcard_receive_command(unsigned char *buffer, int len)
{
int i;
int timeout;
for(i=0;i<len;i++) {
timeout = 2000000;
while(!(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_RX)) {
timeout--;
if(timeout == 0) {
#ifdef MEMCARD_DEBUG
printk("Command receive timeout\n");
#endif
return false;
}
}
buffer[i] = MM_READ(MM_MEMCARD_CMD);
MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_CMD_RX);
}
while(!(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_RX));
#ifdef MEMCARD_DEBUG
printk("<< ");
for(i=0;i<len;i++)
printk("%02x ", buffer[i]);
printk("\n");
#endif
return true;
}
static bool memcard_receive_command_data(unsigned char *command,
unsigned int *data)
{
int i, j;
int timeout;
i = 0;
j = 0;
while(j < 128) {
timeout = 2000000;
while(!(MM_READ(MM_MEMCARD_PENDING) &
(MEMCARD_PENDING_CMD_RX|MEMCARD_PENDING_DAT_RX))) {
timeout--;
if(timeout == 0) {
#ifdef MEMCARD_DEBUG
printk("Command receive timeout\n");
#endif
return false;
}
}
if(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_CMD_RX) {
command[i++] = MM_READ(MM_MEMCARD_CMD);
MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_CMD_RX);
if(i == 6)
/* disable command RX */
MM_WRITE(MM_MEMCARD_ENABLE, MEMCARD_ENABLE_DAT_RX);
}
if(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_DAT_RX) {
data[j++] = MM_READ(MM_MEMCARD_DAT);
MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_DAT_RX);
}
}
/* Get CRC (ignored) */
for(i=0;i<2;i++) {
while(!(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_DAT_RX));
#ifdef MEMCARD_DEBUG
printk("CRC: %08x\n", MM_READ(MM_MEMCARD_DAT));
#endif
MM_WRITE(MM_MEMCARD_PENDING, MEMCARD_PENDING_DAT_RX);
}
while(!(MM_READ(MM_MEMCARD_PENDING) & MEMCARD_PENDING_DAT_RX));
#ifdef MEMCARD_DEBUG
printk("<< %02x %02x %02x %02x %02x %02x\n",
command[0], command[1], command[2], command[3], command[4], command[5]);
#endif
//for(i=0;i<128;i++)
// printk("%08x ", data[i]);
//printk("\n");
return true;
}
static unsigned int block_count;
static int memcard_disk_block_read(rtems_blkdev_request *r)
{
unsigned char b[6];
unsigned int i, nblocks;
unsigned int block;
block = RTEMS_BLKDEV_START_BLOCK(r);
nblocks = r->bufnum;
for(i=0;i<nblocks;i++) {
/* CMD17 - read block */
memcard_start_cmd_tx();
memcard_send_command(17, (block+i)*BLOCK_SIZE);
memcard_start_cmd_dat_rx();
if(!memcard_receive_command_data(b, (unsigned int *)r->bufs[i].buffer))
return -RTEMS_IO_ERROR;
}
rtems_blkdev_request_done(r, RTEMS_SUCCESSFUL);
return 0;
}
static int memcard_disk_block_write(rtems_blkdev_request *r)
{
rtems_blkdev_request_done(r, RTEMS_IO_ERROR);
return 0;
}
static rtems_status_code memcard_init(void)
{
unsigned char b[17];
unsigned int rca;
unsigned int block_shift;
unsigned int c_size;
unsigned int c_size_mult;
MM_WRITE(MM_MEMCARD_CLK2XDIV, 250);
/* CMD0 */
memcard_start_cmd_tx();
memcard_send_command(0, 0);
memcard_send_dummy();
/* CMD8 */
memcard_send_command(8, 0x1aa);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
/* ACMD41 - initialize */
while(1) {
memcard_start_cmd_tx();
memcard_send_command(55, 0);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
memcard_start_cmd_tx();
memcard_send_command(41, 0x00300000);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
if(b[1] & 0x80) break;
#ifdef MEMCARD_DEBUG
printk("Card is busy, retrying\n");
#endif
}
/* CMD2 - get CID */
memcard_start_cmd_tx();
memcard_send_command(2, 0);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 17)) return RTEMS_IO_ERROR;
/* CMD3 - get RCA */
memcard_start_cmd_tx();
memcard_send_command(3, 0);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
rca = (((unsigned int)b[1]) << 8)|((unsigned int)b[2]);
#ifdef MEMCARD_DEBUG
printk("RCA: %04x\n", rca);
#endif
/* CMD9 - get CSD */
memcard_start_cmd_tx();
memcard_send_command(9, rca << 16);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 17)) return RTEMS_IO_ERROR;
if(((b)[0] >> 6) != 0)
return RTEMS_IO_ERROR;
block_shift = ((unsigned int)(b)[5] & 0xf);
c_size = ((((unsigned int)(b)[6] & 0x3) << 10)
+ (((unsigned int)(b)[7]) << 2)
+ ((((unsigned int)(b)[8]) >> 6) & 0x3));
c_size_mult = ((((b)[9] & 0x3) << 1) + (((b)[10] >> 7) & 0x1));
block_count = (c_size + 1) * (1U << (c_size_mult + 2));
/* convert to 512-byte blocks for the sake of simplicity */
if(block_shift < 9)
return RTEMS_IO_ERROR;
block_count <<= block_shift - 9;
/* CMD7 - select card */
memcard_start_cmd_tx();
memcard_send_command(7, rca << 16);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
/* ACMD6 - set bus width */
memcard_start_cmd_tx();
memcard_send_command(55, rca << 16);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
memcard_start_cmd_tx();
memcard_send_command(6, 2);
memcard_start_cmd_rx();
if(!memcard_receive_command(b, 6)) return RTEMS_IO_ERROR;
MM_WRITE(MM_MEMCARD_CLK2XDIV, 3);
return RTEMS_SUCCESSFUL;
}
static int memcard_disk_ioctl(rtems_disk_device *dd, uint32_t req, void *arg)
{
if (req == RTEMS_BLKIO_REQUEST) {
rtems_blkdev_request *r = (rtems_blkdev_request *)arg;
switch (r->req) {
case RTEMS_BLKDEV_REQ_READ:
return memcard_disk_block_read(r);
case RTEMS_BLKDEV_REQ_WRITE:
return memcard_disk_block_write(r);
default:
errno = EINVAL;
return -1;
}
} else if (req == RTEMS_BLKIO_CAPABILITIES) {
*(uint32_t *)arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
return 0;
} else {
errno = EINVAL;
return -1;
}
}
rtems_status_code memcard_register(void)
{
rtems_status_code sc;
sc = memcard_init();
RTEMS_CHECK_SC(sc, "Initialize memory card");
sc = rtems_blkdev_create("/dev/memcard", BLOCK_SIZE, block_count,
memcard_disk_ioctl, NULL);
RTEMS_CHECK_SC(sc, "Create disk device");
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,122 +0,0 @@
/* midi.c
*
* Milkymist MIDI driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <sys/types.h>
#include <rtems.h>
#include <rtems/status-checks.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/libio.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_midi.h>
#define DEVICE_NAME "/dev/midi"
static rtems_id midi_q;
static unsigned char *midi_p = NULL;
static unsigned char midi_msg[3];
static rtems_isr interrupt_handler(rtems_vector_number n)
{
unsigned char msg;
while (MM_READ(MM_MIDI_STAT) & MIDI_STAT_RX_EVT) {
msg = MM_READ(MM_MIDI_RXTX);
MM_WRITE(MM_MIDI_STAT, MIDI_STAT_RX_EVT);
if ((msg & 0xf8) == 0xf8)
continue; /* ignore system real-time */
if (msg & 0x80)
midi_p = midi_msg; /* status byte */
if (!midi_p)
continue; /* ignore extra or unsynchronized data */
*midi_p++ = msg;
if (midi_p == midi_msg+3) {
/* received a complete MIDI message */
rtems_message_queue_send(midi_q, midi_msg, 3);
midi_p = NULL;
}
}
lm32_interrupt_ack(1 << MM_IRQ_MIDI);
}
rtems_device_driver midi_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
rtems_isr_entry dummy;
sc = rtems_io_register_name(DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create MIDI input device");
sc = rtems_message_queue_create(
rtems_build_name('M', 'I', 'D', 'I'),
32,
3,
0,
&midi_q
);
RTEMS_CHECK_SC(sc, "create MIDI queue");
rtems_interrupt_catch(interrupt_handler, MM_IRQ_MIDI, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_MIDI);
/* Only MIDI THRU mode is supported atm */
MM_WRITE(MM_MIDI_CTRL, MIDI_CTRL_RX_INT|MIDI_CTRL_THRU);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver midi_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
uint32_t count;
rtems_message_queue_flush(midi_q, &count);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver midi_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rtems_status_code sc;
sc = rtems_message_queue_receive(
midi_q,
rw_args->buffer,
(size_t *)&rw_args->bytes_moved,
RTEMS_WAIT,
RTEMS_NO_TIMEOUT
);
if(sc == RTEMS_SUCCESSFUL)
return RTEMS_SUCCESSFUL;
else {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
}

View File

@@ -1,143 +0,0 @@
/* pfpu.c
*
* Milkymist PFPU driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/libio.h>
#include <rtems/status-checks.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_pfpu.h>
#define DEVICE_NAME "/dev/pfpu"
static rtems_id done_sem;
static rtems_isr done_handler(rtems_vector_number n)
{
rtems_semaphore_release(done_sem);
lm32_interrupt_ack(1 << MM_IRQ_PFPU);
}
rtems_device_driver pfpu_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
rtems_isr_entry dummy;
sc = rtems_io_register_name(DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create PFPU device");
sc = rtems_semaphore_create(
rtems_build_name('P', 'F', 'P', 'U'),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE,
0,
&done_sem
);
RTEMS_CHECK_SC(sc, "create PFPU done semaphore");
rtems_interrupt_catch(done_handler, MM_IRQ_PFPU, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_PFPU);
return RTEMS_SUCCESSFUL;
}
static void load_program(unsigned int *program, int size)
{
int page;
int word;
volatile unsigned int *pfpu_prog = (unsigned int *)MM_PFPU_CODEBASE;
for (page=0;page<(PFPU_PROGSIZE/PFPU_PAGESIZE);page++) {
MM_WRITE(MM_PFPU_CODEPAGE, page);
for (word=0;word<PFPU_PAGESIZE;word++) {
if (size == 0) return;
pfpu_prog[word] = *program;
program++;
size--;
}
}
}
static void load_registers(float *registers)
{
volatile float *pfpu_regs = (float *)MM_PFPU_DREGBASE;
int i;
for (i=PFPU_SPREG_COUNT;i<PFPU_REG_COUNT;i++)
pfpu_regs[i] = registers[i];
}
static void update_registers(float *registers)
{
volatile float *pfpu_regs = (float *)MM_PFPU_DREGBASE;
int i;
for (i=PFPU_SPREG_COUNT;i<PFPU_REG_COUNT;i++)
registers[i] = pfpu_regs[i];
}
static rtems_status_code pfpu_execute(struct pfpu_td *td)
{
rtems_status_code sc;
load_program(td->program, td->progsize);
load_registers(td->registers);
MM_WRITE(MM_PFPU_MESHBASE, (unsigned int)td->output);
MM_WRITE(MM_PFPU_HMESHLAST, td->hmeshlast);
MM_WRITE(MM_PFPU_VMESHLAST, td->vmeshlast);
MM_WRITE(MM_PFPU_CTL, PFPU_CTL_START);
sc = rtems_semaphore_obtain(done_sem, RTEMS_WAIT, 10);
if (sc != RTEMS_SUCCESSFUL)
return sc;
if (td->update) {
update_registers(td->registers);
if (td->invalidate) {
__asm__ volatile( /* Invalidate Level-1 data cache */
"wcsr DCC, r0\n"
"nop\n"
);
}
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver pfpu_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
args->ioctl_return = -1;
if (args->command != PFPU_EXECUTE)
return RTEMS_UNSATISFIED;
if (pfpu_execute((struct pfpu_td *)args->buffer) != RTEMS_SUCCESSFUL)
return RTEMS_UNSATISFIED;
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
}

View File

@@ -1,78 +0,0 @@
/* timer.c
*
* This file manages the benchmark timer used by the RTEMS Timing
* Test Suite. Each measured time period is demarcated by calls to
* benchmark_timer_initialize() and benchmark_timer_read().
* benchmark_timer_read() usually returns the number of microseconds
* since benchmark_timer_initialize() exitted.
*
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) Yann Sionneau <yann.sionneau@telecom-sudparis.eu> (GSoC 2010)
* Telecom SudParis
*/
#include <rtems.h>
#include <bsp.h>
#include <rtems/btimer.h>
#include <rtems/bspIo.h>
#include "../include/system_conf.h"
#include "../../shared/clock/clock.h"
bool benchmark_timer_find_average_overhead;
void benchmark_timer_initialize(void)
{
MM_WRITE(MM_TIMER1_COMPARE, 0xffffffff);
MM_WRITE(MM_TIMER1_COUNTER, 0);
MM_WRITE(MM_TIMER1_CONTROL, TIMER_ENABLE);
}
/*
* The following controls the behavior of benchmark_timer_read().
*
* AVG_OVEREHAD is the overhead for starting and stopping the timer. It
* is usually deducted from the number returned.
*
* LEAST_VALID is the lowest number this routine should trust. Numbers
* below this are "noise" and zero is returned.
*/
#define AVG_OVERHEAD 4 /* It typically takes X.X microseconds */
/* (Y countdowns) to start/stop the timer. */
/* This value is in microseconds. */
#define LEAST_VALID 4 /* Don't trust a clicks value lower than this */
benchmark_timer_t benchmark_timer_read(void)
{
uint32_t ticks;
uint32_t total;
ticks = MM_READ(MM_TIMER1_COUNTER);
if (ticks == 0xffffffff)
printk("Timer overflow!\n");
total = ticks / (MM_READ(MM_FREQUENCY) / 1000000);
if (benchmark_timer_find_average_overhead)
return total;
else
{
if (total < LEAST_VALID)
return 0;
return (total - AVG_OVERHEAD);
}
}
void benchmark_timer_disable_subtracting_average_overhead(
bool find_flag
)
{
benchmark_timer_find_average_overhead = find_flag;
}

View File

@@ -1,161 +0,0 @@
/* tmu.c
*
* Milkymist TMU driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/libio.h>
#include <rtems/status-checks.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_tmu.h>
#define DEVICE_NAME "/dev/tmu"
static rtems_id done_sem;
static rtems_isr done_handler(rtems_vector_number n)
{
rtems_semaphore_release(done_sem);
lm32_interrupt_ack(1 << MM_IRQ_TMU);
}
rtems_device_driver tmu_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
rtems_isr_entry dummy;
sc = rtems_io_register_name(DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create TMU device");
sc = rtems_semaphore_create(
rtems_build_name('T', 'M', 'U', ' '),
0,
RTEMS_SIMPLE_BINARY_SEMAPHORE,
0,
&done_sem
);
RTEMS_CHECK_SC(sc, "create TMU done semaphore");
rtems_interrupt_catch(done_handler, MM_IRQ_TMU, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_TMU);
return RTEMS_SUCCESSFUL;
}
static void invalidate_l2(void)
{
volatile char *flushbase = (char *)FMLBRG_FLUSH_BASE;
int i, offset;
offset = 0;
for (i=0;i<FMLBRG_LINE_COUNT;i++) {
flushbase[offset] = 0;
offset += FMLBRG_LINE_LENGTH;
}
}
static bool invalidate_after;
static void tmu_start(struct tmu_td *td)
{
if (td->invalidate_before)
invalidate_l2();
MM_WRITE(MM_TMU_HMESHLAST, td->hmeshlast);
MM_WRITE(MM_TMU_VMESHLAST, td->vmeshlast);
MM_WRITE(MM_TMU_BRIGHTNESS, td->brightness);
MM_WRITE(MM_TMU_CHROMAKEY, td->chromakey);
MM_WRITE(MM_TMU_VERTICESADR, (unsigned int)td->vertices);
MM_WRITE(MM_TMU_TEXFBUF, (unsigned int)td->texfbuf);
MM_WRITE(MM_TMU_TEXHRES, td->texhres);
MM_WRITE(MM_TMU_TEXVRES, td->texvres);
MM_WRITE(MM_TMU_TEXHMASK, td->texhmask);
MM_WRITE(MM_TMU_TEXVMASK, td->texvmask);
MM_WRITE(MM_TMU_DSTFBUF, (unsigned int)td->dstfbuf);
MM_WRITE(MM_TMU_DSTHRES, td->dsthres);
MM_WRITE(MM_TMU_DSTVRES, td->dstvres);
MM_WRITE(MM_TMU_DSTHOFFSET, td->dsthoffset);
MM_WRITE(MM_TMU_DSTVOFFSET, td->dstvoffset);
MM_WRITE(MM_TMU_DSTSQUAREW, td->dstsquarew);
MM_WRITE(MM_TMU_DSTSQUAREH, td->dstsquareh);
MM_WRITE(MM_TMU_ALPHA, td->alpha);
MM_WRITE(MM_TMU_CTL, td->flags|TMU_CTL_START);
invalidate_after = td->invalidate_after;
}
static rtems_status_code tmu_finalize(void)
{
rtems_status_code sc;
sc = rtems_semaphore_obtain(done_sem, RTEMS_WAIT, 100);
if (sc != RTEMS_SUCCESSFUL)
return sc;
if (invalidate_after) {
invalidate_l2();
__asm__ volatile( /* Invalidate Level-1 data cache */
"wcsr DCC, r0\n"
"nop\n"
);
}
return RTEMS_SUCCESSFUL;
}
rtems_device_driver tmu_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
struct tmu_td *td = (struct tmu_td *)args->buffer;
rtems_status_code sc;
switch (args->command) {
case TMU_EXECUTE:
tmu_start(td);
sc = tmu_finalize();
break;
case TMU_EXECUTE_NONBLOCK:
tmu_start(td);
sc = RTEMS_SUCCESSFUL;
break;
case TMU_EXECUTE_WAIT:
sc = tmu_finalize();
break;
default:
sc = RTEMS_UNSATISFIED;
break;
}
if (sc == RTEMS_SUCCESSFUL)
args->ioctl_return = 0;
else
args->ioctl_return = -1;
return sc;
}

View File

@@ -1,32 +0,0 @@
/**
* @file
* @ingroup lm32_milkymist_usbinput RTEMSBSPsLM32SharedMilkymistOne
* @brief Milkymist USB input devices driver
*/
/* comloc.h
*
* Milkymist USB input devices driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010 Sebastien Bourdeauducq
*/
#ifndef __COMLOC_H_
#define __COMLOC_H_
#define COMLOCV(x) (*(volatile unsigned char *)(x))
#define COMLOC_DEBUG_PRODUCE COMLOCV(MM_SOFTUSB_DMEM_BASE+0x1000)
#define COMLOC_DEBUG(offset) COMLOCV(MM_SOFTUSB_DMEM_BASE+0x1001+offset)
#define COMLOC_MEVT_PRODUCE COMLOCV(MM_SOFTUSB_DMEM_BASE+0x1101)
#define COMLOC_MEVT(offset) COMLOCV(MM_SOFTUSB_DMEM_BASE+0x1102+offset)
#define COMLOC_KEVT_PRODUCE COMLOCV(MM_SOFTUSB_DMEM_BASE+0x1142)
#define COMLOC_KEVT(offset) COMLOCV(MM_SOFTUSB_DMEM_BASE+0x1143+offset)
#define COMLOC_MIDI_PRODUCE COMLOCV(MM_SOFTUSB_DMEM_BASE+0x1183)
#define COMLOC_MIDI(offset) COMLOCV(MM_SOFTUSB_DMEM_BASE+0x1184+offset)
#endif /* __COMLOC_H_ */

View File

@@ -1,179 +0,0 @@
/* usbinput.c
*
* Milkymist USB input devices driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011, 2012 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/libio.h>
#include <rtems/status-checks.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_usbinput.h>
#include "comloc.h"
#define DEVICE_NAME "/dev/usbinput"
static int mouse_consume;
static int keyboard_consume;
static int midi_consume;
static rtems_id event_q;
static rtems_isr interrupt_handler(rtems_vector_number n)
{
unsigned char msg[8];
int i;
lm32_interrupt_ack(1 << MM_IRQ_USB);
while(mouse_consume != COMLOC_MEVT_PRODUCE) {
for(i=0;i<4;i++)
msg[i] = COMLOC_MEVT(4*mouse_consume+i);
rtems_message_queue_send(event_q, msg, 4);
mouse_consume = (mouse_consume + 1) & 0x0f;
}
while(keyboard_consume != COMLOC_KEVT_PRODUCE) {
for(i=0;i<8;i++)
msg[i] = COMLOC_KEVT(8*keyboard_consume+i);
rtems_message_queue_send(event_q, msg, 8);
keyboard_consume = (keyboard_consume + 1) & 0x07;
}
while(midi_consume != COMLOC_MIDI_PRODUCE) {
for(i=0;i<3;i++)
msg[i] = COMLOC_MIDI(4*midi_consume+i+1);
rtems_message_queue_send(event_q, msg, 3);
midi_consume = (midi_consume + 1) & 0x0f;
}
}
rtems_device_driver usbinput_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
rtems_isr_entry dummy;
MM_WRITE(MM_SOFTUSB_CONTROL, SOFTUSB_CONTROL_RESET);
mouse_consume = 0;
keyboard_consume = 0;
midi_consume = 0;
sc = rtems_io_register_name(DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create USB input device");
sc = rtems_message_queue_create(
rtems_build_name('U', 'S', 'B', 'I'),
64,
8,
0,
&event_q
);
RTEMS_CHECK_SC(sc, "create USB event queue");
rtems_interrupt_catch(interrupt_handler, MM_IRQ_USB, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_USB);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver usbinput_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
uint32_t count;
rtems_message_queue_flush(event_q, &count);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver usbinput_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
rtems_status_code sc;
if(rw_args->count < 8) {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
sc = rtems_message_queue_receive(
event_q,
rw_args->buffer,
(size_t *)&rw_args->bytes_moved,
RTEMS_WAIT,
RTEMS_NO_TIMEOUT
);
if(sc == RTEMS_SUCCESSFUL)
return RTEMS_SUCCESSFUL;
else {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
}
static void load_firmware(const unsigned char *firmware, int length)
{
int i, nwords;
volatile unsigned int *usb_dmem
= (volatile unsigned int *)MM_SOFTUSB_DMEM_BASE;
volatile unsigned int *usb_pmem
= (volatile unsigned int *)MM_SOFTUSB_PMEM_BASE;
MM_WRITE(MM_SOFTUSB_CONTROL, SOFTUSB_CONTROL_RESET);
for(i=0;i<SOFTUSB_DMEM_SIZE/4;i++)
usb_dmem[i] = 0;
for(i=0;i<SOFTUSB_PMEM_SIZE/2;i++)
usb_pmem[i] = 0;
nwords = (length+1)/2;
for(i=0;i<nwords;i++)
usb_pmem[i] = ((unsigned int)(firmware[2*i]))
|((unsigned int)(firmware[2*i+1]) << 8);
MM_WRITE(MM_SOFTUSB_CONTROL, 0);
}
rtems_device_driver usbinput_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
struct usbinput_firmware_description *fd
= (struct usbinput_firmware_description *)args->buffer;
if(args->command == USBINPUT_LOAD_FIRMWARE) {
load_firmware(fd->data, fd->length);
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
} else {
args->ioctl_return = -1;
return RTEMS_UNSATISFIED;
}
}

View File

@@ -1,132 +0,0 @@
/* versions.c
*
* Milkymist versioning driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <rtems.h>
#include <rtems/status-checks.h>
#include <bsp.h>
#include <rtems/libio.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_versions.h>
#define SOC_DEVICE_NAME "/dev/soc"
#define PCB_DEVICE_NAME "/dev/pcb"
#define PCBREV_DEVICE_NAME "/dev/pcb_rev"
rtems_device_driver versions_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
sc = rtems_io_register_name(SOC_DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create SoC version device");
sc = rtems_io_register_name(PCB_DEVICE_NAME, major, 1);
RTEMS_CHECK_SC(sc, "create PCB type device");
sc = rtems_io_register_name(PCBREV_DEVICE_NAME, major, 2);
RTEMS_CHECK_SC(sc, "create PCB revision device");
return RTEMS_SUCCESSFUL;
}
static int get_soc_version(char *buffer)
{
char fmt[13];
char *version;
int len;
unsigned int id;
unsigned int major, minor, subminor, rc;
id = MM_READ(MM_SYSTEM_ID);
major = (id & 0xf0000000) >> 28;
minor = (id & 0x0f000000) >> 24;
subminor = (id & 0x00f00000) >> 20;
rc = (id & 0x000f0000) >> 16;
version = fmt;
version += sprintf(version, "%u.%u", major, minor);
if (subminor != 0)
version += sprintf(version, ".%u", subminor);
if (rc != 0)
version += sprintf(version, "RC%u", rc);
len = version - fmt;
memcpy(buffer, fmt, len);
return len;
}
static int get_pcb_type(char *buffer)
{
unsigned int id;
id = MM_READ(MM_SYSTEM_ID);
buffer[0] = (id & 0x0000ff00) >> 8;
buffer[1] = id & 0x000000ff;
return 2;
}
static int get_pcb_revision(char *buffer)
{
unsigned int v;
v = MM_READ(MM_GPIO_IN);
v = (v & 0x78) >> 3;
buffer[0] = '0' + v;
return 1;
}
rtems_device_driver versions_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
if(rw_args->offset != 0) {
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
switch (minor) {
case 0:
if (rw_args->count < 12) {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
rw_args->bytes_moved = get_soc_version((char *)rw_args->buffer);
return RTEMS_SUCCESSFUL;
case 1:
if (rw_args->count < 2) {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
rw_args->bytes_moved = get_pcb_type((char *)rw_args->buffer);
return RTEMS_SUCCESSFUL;
case 2:
if (rw_args->count < 1) {
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}
rw_args->bytes_moved = get_pcb_revision((char *)rw_args->buffer);
return RTEMS_SUCCESSFUL;
}
rw_args->bytes_moved = 0;
return RTEMS_UNSATISFIED;
}

View File

@@ -1,391 +0,0 @@
/* video.c
*
* Milkymist video input driver for RTEMS
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
*/
#define RTEMS_STATUS_CHECKS_USE_PRINTK
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq-generic.h>
#include <rtems/libio.h>
#include <rtems/status-checks.h>
#include <rtems/bspIo.h>
#include "../include/system_conf.h"
#include <bsp/milkymist_video.h>
#define DEVICE_NAME "/dev/video"
#define N_BUFFERS 3
#define FRAME_W 720
#define FRAME_H 288
static bool buffers_locked[N_BUFFERS];
static void *buffers[N_BUFFERS];
static int last_buffer;
static int current_buffer;
static rtems_isr frame_handler(rtems_vector_number n)
{
int remaining_attempts;
lm32_interrupt_ack(1 << MM_IRQ_VIDEOIN);
last_buffer = current_buffer;
/* get a new buffer */
remaining_attempts = N_BUFFERS;
do {
current_buffer++;
if(current_buffer == N_BUFFERS)
current_buffer = 0;
remaining_attempts--;
} while(buffers_locked[current_buffer] && (remaining_attempts > 0));
MM_WRITE(MM_BT656_BASE, (unsigned int)buffers[current_buffer]);
if(buffers_locked[current_buffer])
printk("Failed to find unlocked buffer\n");
}
static void i2c_delay(void)
{
unsigned int i;
for(i=0;i<1000;i++) __asm__("nop");
}
/* I2C bit-banging functions from http://en.wikipedia.org/wiki/I2c */
static unsigned int i2c_read_bit(void)
{
unsigned int bit;
/* Let the slave drive data */
MM_WRITE(MM_BT656_I2C, 0);
i2c_delay();
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDC);
i2c_delay();
bit = MM_READ(MM_BT656_I2C) & BT656_I2C_SDAIN;
i2c_delay();
MM_WRITE(MM_BT656_I2C, 0);
return bit;
}
static void i2c_write_bit(unsigned int bit)
{
if(bit) {
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDAOE|BT656_I2C_SDAOUT);
} else {
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDAOE);
}
i2c_delay();
MM_WRITE(MM_BT656_I2C, MM_READ(MM_BT656_I2C) | BT656_I2C_SDC);
i2c_delay();
MM_WRITE(MM_BT656_I2C, MM_READ(MM_BT656_I2C) & ~BT656_I2C_SDC);
}
static int i2c_started;
static void i2c_start_cond(void)
{
if(i2c_started) {
/* set SDA to 1 */
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDAOE|BT656_I2C_SDAOUT);
i2c_delay();
MM_WRITE(MM_BT656_I2C, MM_READ(MM_BT656_I2C) | BT656_I2C_SDC);
}
/* SCL is high, set SDA from 1 to 0 */
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDAOE|BT656_I2C_SDC);
i2c_delay();
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDAOE);
i2c_started = 1;
}
static void i2c_stop_cond(void)
{
/* set SDA to 0 */
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDAOE);
i2c_delay();
/* Clock stretching */
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDAOE|BT656_I2C_SDC);
/* SCL is high, set SDA from 0 to 1 */
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDC);
i2c_delay();
i2c_started = 0;
}
static unsigned int i2c_write(unsigned char byte)
{
unsigned int bit;
unsigned int ack;
for(bit = 0; bit < 8; bit++) {
i2c_write_bit(byte & 0x80);
byte <<= 1;
}
ack = !i2c_read_bit();
return ack;
}
static unsigned char i2c_read(int ack)
{
unsigned char byte = 0;
unsigned int bit;
for(bit = 0; bit < 8; bit++) {
byte <<= 1;
byte |= i2c_read_bit();
}
i2c_write_bit(!ack);
return byte;
}
static unsigned char read_reg(unsigned char addr)
{
unsigned char r;
i2c_start_cond();
i2c_write(0x40);
i2c_write(addr);
i2c_start_cond();
i2c_write(0x41);
r = i2c_read(0);
i2c_stop_cond();
return r;
}
static void write_reg(unsigned char addr, unsigned char val)
{
i2c_start_cond();
i2c_write(0x40);
i2c_write(addr);
i2c_write(val);
i2c_stop_cond();
}
static const char vreg_addr[] = {
0x1d, 0xc3, 0xc4
};
static const char vreg_dat[] = {
0x40, 0x05, 0x80
};
rtems_device_driver video_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_status_code sc;
rtems_isr_entry dummy;
int i;
MM_WRITE(MM_BT656_I2C, BT656_I2C_SDC);
sc = rtems_io_register_name(DEVICE_NAME, major, 0);
RTEMS_CHECK_SC(sc, "create video input device");
rtems_interrupt_catch(frame_handler, MM_IRQ_VIDEOIN, &dummy);
bsp_interrupt_vector_enable(MM_IRQ_VIDEOIN);
for(i=0;i<sizeof(vreg_addr);i++)
write_reg(vreg_addr[i], vreg_dat[i]);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver video_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
int i;
int status;
for(i=0;i<N_BUFFERS;i++) {
status = posix_memalign(&buffers[i], 32, 2*FRAME_W*FRAME_H);
if(status != 0) {
i--;
while(i > 0) {
free(buffers[i]);
i--;
}
return RTEMS_UNSATISFIED;
}
}
last_buffer = -1;
current_buffer = 0;
MM_WRITE(MM_BT656_BASE, (unsigned int)buffers[current_buffer]);
MM_WRITE(MM_BT656_FILTERSTATUS, BT656_FILTER_FIELD1);
return RTEMS_SUCCESSFUL;
}
rtems_device_driver video_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
int i;
MM_WRITE(MM_BT656_FILTERSTATUS, 0);
while(MM_READ(MM_BT656_FILTERSTATUS) & BT656_FILTER_INFRAME);
for(i=0;i<N_BUFFERS;i++)
free(buffers[i]);
return RTEMS_SUCCESSFUL;
}
static void invalidate_caches(void)
{
volatile char *flushbase = (char *)FMLBRG_FLUSH_BASE;
int i, offset;
offset = 0;
for (i=0;i<FMLBRG_LINE_COUNT;i++) {
flushbase[offset] = 0;
offset += FMLBRG_LINE_LENGTH;
}
__asm__ volatile( /* Invalidate Level-1 data cache */
"wcsr DCC, r0\n"
"nop\n"
);
}
static void set_format(int format)
{
switch(format) {
case VIDEO_FORMAT_CVBS6:
write_reg(0x00, 0x00);
write_reg(0xc3, 0x05);
write_reg(0xc4, 0x80);
break;
case VIDEO_FORMAT_CVBS5:
write_reg(0x00, 0x00);
write_reg(0xc3, 0x0d);
write_reg(0xc4, 0x80);
break;
case VIDEO_FORMAT_CVBS4:
write_reg(0x00, 0x00);
write_reg(0xc3, 0x04);
write_reg(0xc4, 0x80);
break;
case VIDEO_FORMAT_SVIDEO:
write_reg(0x00, 0x06);
write_reg(0xc3, 0xd5);
write_reg(0xc4, 0x80);
break;
case VIDEO_FORMAT_COMPONENT:
write_reg(0x00, 0x09);
write_reg(0xc3, 0x45);
write_reg(0xc4, 0x8d);
break;
}
}
rtems_device_driver video_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
rtems_libio_ioctl_args_t *args = arg;
unsigned int *a = (unsigned int *)args->buffer;
rtems_status_code sc;
switch (args->command) {
case VIDEO_BUFFER_LOCK:
if (last_buffer == -1) {
*a = 0;
} else {
bsp_interrupt_vector_disable(MM_IRQ_VIDEOIN);
if(*a) invalidate_caches();
*a = (unsigned int)buffers[last_buffer];
buffers_locked[last_buffer] = true;
bsp_interrupt_vector_enable(MM_IRQ_VIDEOIN);
}
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_BUFFER_UNLOCK: {
int i;
for(i=0;i<N_BUFFERS;i++) {
if ((unsigned int)buffers[i] == (unsigned int)a) {
buffers_locked[i] = false;
break;
}
}
sc = RTEMS_SUCCESSFUL;
break;
}
case VIDEO_SET_BRIGHTNESS:
write_reg(0x0a, (unsigned int)a);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_GET_BRIGHTNESS:
*a = read_reg(0x0a);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_SET_CONTRAST:
write_reg(0x08, (unsigned int)a);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_GET_CONTRAST:
*a = read_reg(0x08);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_SET_HUE:
write_reg(0x0b, (unsigned int)a);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_GET_HUE:
*a = read_reg(0x0b);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_GET_SIGNAL:
*a = read_reg(0x10);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_SET_REGISTER:
write_reg(((unsigned int)a & 0xffff0000) >> 16,
(unsigned int)a & 0x0000ffff);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_GET_REGISTER:
*a = read_reg(*a);
sc = RTEMS_SUCCESSFUL;
break;
case VIDEO_SET_FORMAT:
set_format((int)a);
sc = RTEMS_SUCCESSFUL;
break;
default:
sc = RTEMS_UNSATISFIED;
break;
}
if (sc == RTEMS_SUCCESSFUL)
args->ioctl_return = 0;
else
args->ioctl_return = -1;
return sc;
}

View File

@@ -1,51 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* Default bsp_reset() for LM32 BSPs which can run on the GDB simulator
*/
/*
* COPYRIGHT (c) 1989-2015.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*/
#include <bsp/bootcard.h>
void bsp_reset( rtems_fatal_source source, rtems_fatal_code code )
{
(void) source;
(void) code;
/*
* If on the GDB simulator, trap to it and exit.
*/
#if LM32_ON_SIMULATOR
__asm__ volatile ( "mvi r8, 1" ); /* 1 is SYS_exit */
__asm__ volatile ( "scall" );
#endif
RTEMS_UNREACHABLE();
}

View File

@@ -1,54 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* This routine starts the application. It includes application,
* board, and monitor specific initialization and configuration.
* The generic CPU dependent initialization has been performed
* before this routine is invoked.
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
* 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.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#include <string.h>
#include <bsp.h>
#include <bsp/bootcard.h>
#include "../include/system_conf.h"
#include "../console/uart.h"
/*
* bsp_start
*
* This routine does the bulk of the system initialization.
*/
void bsp_start(void)
{
/* Setup console baud rate */
BSP_uart_init(UART_BAUD_RATE);
}

View File

@@ -1,160 +0,0 @@
/* LM32 startup code
*
* This is the entry point on reset and when loading the
* executive from a bootloader.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#include "bspopts.h"
.section .boot,"a",@progbits
.align 4
.globl start
.type start,@function
.globl _start
.type _start,@function
.globl __start
.type __start,@function
.globl LatticeDDInit
.type LatticeDDInit,@function
.globl crt0
.type crt0,@function
LatticeDDInit:
__start:
_start:
start:
/* Clear r0 */
xor r0,r0,r0
/* Disable interrupts */
wcsr IE, r0
/* Mask all interrupts */
wcsr IM,r0
/* Set exception base address */
mvhi r1, hi(start)
ori r1, r1, lo(start)
wcsr EBA, r1
bi crt0
nop
/*
* Unused handlers call debug handlers
*/
breakpoint_handler:
rcsr r7, DEBA
addi r7, r7, 32
b r7
nop
nop
nop
nop
nop
instruction_bus_error_handler:
rcsr r7, DEBA
addi r7, r7, 64
b r7
nop
nop
nop
nop
nop
watchpoint_handler:
rcsr r7, DEBA
addi r7, r7, 96
b r7
nop
nop
nop
nop
nop
data_bus_error_handler:
rcsr r7, DEBA
addi r7, r7, 128
b r7
nop
nop
nop
nop
nop
divide_by_zero_handler:
rcsr r7, DEBA
addi r7, r7, 160
b r7
nop
nop
nop
nop
nop
interrupt_handler:
.extern _ISR_Handler
mvhi r0, hi(_ISR_Handler)
ori r0, r0, lo(_ISR_Handler)
b r0
nop
nop
nop
nop
nop
system_call_handler:
rcsr r7, DEBA
addi r7, r7, 224
b r7
nop
nop
nop
nop
nop
crt0:
/* Flush data cache */
addi r1, r0, 1
wcsr DCC, r1
nop
nop
nop
nop
/* Flush Instruction Cache */
wcsr ICC, r1
nop
nop
nop
nop
/* Initialize stack pointer */
mvhi sp, hi(_ISR_Stack_area_end-4)
ori sp, sp, lo(_ISR_Stack_area_end-4)
/* Initialize global pointer */
mvhi gp, hi(_edata)
ori gp, gp, lo(_edata)
/* Clear bss */
mvhi r1, hi(_clear_start)
ori r1, r1, lo(_clear_start)
mvhi r3, hi(_clear_end)
ori r3, r3, lo(_clear_end)
.clear_bss:
be r1, r3, .end_clear_bss
sw (r1+0), r0
addi r1, r1, 4
bi .clear_bss
.end_clear_bss:
mvi r1, 0
be r4, r0, .no_rescue
mvhi r1, hi(.rescue_str)
ori r1, r1, lo(.rescue_str)
.no_rescue:
mvhi r7, hi(boot_card)
ori r7, r7, lo(boot_card)
call r7
# boot_card returns when RTEMS is shutdown
.dead_end:
bi .dead_end
.section .rodata
.rescue_str:
.ascii "rescue"

View File

@@ -1,102 +0,0 @@
/**
* @file
*
* @brief LM32 CPU Dependent Source
*/
/*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/cpuimpl.h>
#include <rtems/score/isr.h>
/* _CPU_Initialize
*
* This routine performs processor dependent initialization.
*
* INPUT PARAMETERS: NONE
*
* LM32 Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_Initialize(void)
{
/*
* If there is not an easy way to initialize the FP context
* during Context_Initialize, then it is usually easier to
* save an "uninitialized" FP context here and copy it to
* the task's during Context_Initialize.
*/
/* FP context initialization support goes here */
}
uint32_t _CPU_ISR_Get_level( void )
{
/*
* This routine returns the current interrupt level.
*/
return 0;
}
void _CPU_ISR_install_vector(
uint32_t vector,
CPU_ISR_handler new_handler,
CPU_ISR_handler *old_handler
)
{
*old_handler = _ISR_Vector_table[ vector ];
/*
* We put the actual user ISR address in '_ISR_vector_table'. This will
* be used by the _ISR_Handler so the user gets control.
*/
_ISR_Vector_table[ vector ] = new_handler;
}
/*
* _CPU_Thread_Idle_body
*
* NOTES:
*
* 1. This is the same as the regular CPU independent algorithm.
*
* 2. If you implement this using a "halt", "idle", or "shutdown"
* instruction, then don't forget to put it in an infinite loop.
*
* 3. Be warned. Some processors with onboard DMA have been known
* to stop the DMA if the CPU were put in IDLE mode. This might
* also be a problem with other on-chip peripherals. So use this
* hook with caution.
*
* LM32 Specific Information:
*
* XXX document implementation including references if appropriate
*/
void *_CPU_Thread_Idle_body( uintptr_t ignored )
{
for( ; ; ) {
/* The LM32 softcore itself hasn't any HLT instruction. But the
* LM32 qemu target interprets this nop instruction as HLT.
*/
__asm__ volatile("and r0, r0, r0");
}
}

View File

@@ -1,203 +0,0 @@
/*
* This file contains all assembly code for the
* LM32 implementation of RTEMS.
*
* Derived from no_cpu/cpu_asm.S, copyright (c) 1989-1999,
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*
* Michael Walle <michael@walle.cc>, 2009
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/asm.h>
#include <rtems/score/cpu_asm.h>
/* void _CPU_Context_switch(run_context, heir_context)
*
* This routine performs a normal non-FP context switch.
*
* LM32 Specific Information:
*
* Saves/restores all callee-saved general purpose registers as well as
* the stack pointer, return address and interrupt enable status register
* to/from the context.
*
*/
.globl _CPU_Context_switch
_CPU_Context_switch:
sw (r1+0), r11 /* r1 is the first argument */
sw (r1+4), r12
sw (r1+8), r13
sw (r1+12), r14
sw (r1+16), r15
sw (r1+20), r16
sw (r1+24), r17
sw (r1+28), r18
sw (r1+32), r19
sw (r1+36), r20
sw (r1+40), r21
sw (r1+44), r22
sw (r1+48), r23
sw (r1+52), r24
sw (r1+56), r25
sw (r1+60), gp
sw (r1+64), fp
sw (r1+68), sp
sw (r1+72), ra
rcsr r3, IE
sw (r1+76), r3
.extern _exception_stack_frame
mvhi r3, hi(_exception_stack_frame)
ori r3, r3, lo(_exception_stack_frame)
lw r4, (r3+0)
be r4, r0, 2f
1:
lw r5, (r4+44)
sw (r3+0), r0
bi 3f
2:
mvhi r5, hi(_Thread_Dispatch)
ori r5, r5, lo(_Thread_Dispatch)
3:
sw (r1+80), r5
_CPU_Context_switch_restore:
lw r11, (r2+0) /* r2 is the second argument */
lw r12, (r2+4)
lw r13, (r2+8)
lw r14, (r2+12)
lw r15, (r2+16)
lw r16, (r2+20)
lw r17, (r2+24)
lw r18, (r2+28)
lw r19, (r2+32)
lw r20, (r2+36)
lw r21, (r2+40)
lw r22, (r2+44)
lw r23, (r2+48)
lw r24, (r2+52)
lw r25, (r2+56)
lw gp, (r2+60)
lw fp, (r2+64)
lw sp, (r2+68)
lw ra, (r2+72)
lw r3, (r2+76)
wcsr IE, r3
ret
/*
* _CPU_Context_restore
*
* This routine is generally used only to restart self in an
* efficient manner. It may simply be a label in _CPU_Context_switch.
*
* LM32 Specific Information:
*
* Moves argument #1 to #2 and branches to the restore part of the
* context switch code above.
*/
.globl _CPU_Context_restore
_CPU_Context_restore:
mv r2, r1
bi _CPU_Context_switch_restore
/* void _ISR_Handler()
*
* This routine provides the RTEMS interrupt management.
*
* LM32 Specific Information:
*
* Saves all the caller-saved general purpose registers as well as the
* return address, exception return address and breakpoint return address
* (the latter may be unnecessary) onto the stack, which is either the task
* stack (in case of a interrupted task) or the interrupt stack (if an
* interrupt was interrupted).
* After that, it figures out the pending interrupt with the highest
* priority and calls the main ISR handler written in C, which in turn
* handles interrupt nesting, software interrupt stack setup etc and
* finally calls the user ISR.
* At the end the saved registers are restored.
*
*/
.globl _ISR_Handler
_ISR_Handler:
xor r0, r0, r0
addi sp, sp, -52
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
sw (sp+16), r4
sw (sp+20), r5
sw (sp+24), r6
sw (sp+28), r7
sw (sp+32), r8
sw (sp+36), r9
sw (sp+40), r10
sw (sp+44), ra
sw (sp+48), ea
sw (sp+52), ba
/*
* Scan through IP & IM bits starting from LSB until irq vector is
* found. The vector is stored in r1, which is the first argument for
* __ISR_Handler.
*/
rcsr r2, IP
rcsr r3, IM
mv r1, r0 /* r1: counter for the vector number */
and r2, r2, r3 /* r2: pending irqs, which are enabled */
mvi r3, 1 /* r3: register for the walking 1 */
/*
* If r2 is zero, there was no interrupt.
* This should never happen!
*/
be r2, r0, exit_isr
find_irq:
and r4, r2, r3
bne r4, r0, found_irq
sli r3, r3, 1
addi r1, r1, 1
bi find_irq
found_irq:
/*
* Call __ISR_Handler for further processing.
* r1 is the vector number, calculated above
* r2 is the pointer to the CPU_Interrupt_frame
*/
addi r2, sp, 4
.extern __ISR_Handler
mvhi r3, hi(__ISR_Handler)
ori r3, r3, lo(__ISR_Handler)
call r3
exit_isr:
/* Restore the saved registers */
lw r1, (sp+4)
lw r2, (sp+8)
lw r3, (sp+12)
lw r4, (sp+16)
lw r5, (sp+20)
lw r6, (sp+24)
lw r7, (sp+28)
lw r8, (sp+32)
lw r9, (sp+36)
lw r10, (sp+40)
lw ra, (sp+44)
lw ea, (sp+48)
lw ba, (sp+52)
addi sp, sp, 52
eret

View File

@@ -1,34 +0,0 @@
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2MSB
#define ELF32_MACHDEP_ID_CASES \
case EM_LATTICEMICO32: \
break;
#define ELF32_MACHDEP_ID EM_LATTICEMICO32
#define EF_MACH32_MACH 0x00000001
//#define EF_BLACKFIN
#define ARCH_ELFSIZE 32
#define R_LM32_NONE 0
#define R_LM32_8 1
#define R_LM32_16 2
#define R_LM32_32 3
#define R_LM32_HI16 4
#define R_LM32_LO16 5
#define R_LM32_GPREL16 6
#define R_LM32_CALL 7
#define R_LM32_BRANCH 8
#define R_LM32_GNU_VTINHERIT 9
#define R_LM32_GNU_VTENTRY 10
#define R_LM32_16_GOT 11
#define R_LM32_GOTOFF_HI16 12
#define R_LM32_GOTOFF_LO16 13
#define R_LM32_COPY 14
#define R_LM32_GLOT_DAT 15
#define R_LM32_JMP_SLOT 16
#define R_LM32_RELATIVE 17
#define R_TYPE(name) __CONCAT(R_LM32_,name)

View File

@@ -1,138 +0,0 @@
/**
* @file
*
* @brief Address the Problems Caused by Incompatible Flavor of
* Assemblers and Toolsets
*
* This include file attempts to address the problems
* caused by incompatible flavors of assemblers and
* toolsets. It primarily addresses variations in the
* use of leading underscores on symbols and the requirement
* that register names be preceded by a %.
*
* NOTE: The spacing in the use of these macros
* is critical to them working as advertised.
*/
/*
* COPYRIGHT:
*
* This file is based on similar code found in newlib available
* from ftp.cygnus.com. The file which was used had no copyright
* notice. This file is freely distributable as long as the source
* of the file is noted. This file is:
*
* COPYRIGHT (c) 1994-2006.
* On-Line Applications Research Corporation (OAR).
*/
#ifndef _RTEMS_ASM_H
#define _RTEMS_ASM_H
/*
* Indicate we are in an assembly file and get the basic CPU definitions.
*/
#ifndef ASM
#define ASM
#endif
#include <rtems/score/cpuopts.h>
#include <rtems/score/lm32.h>
/**
* @defgroup RTEMSScoreCPUlm32ASM lm32 Assembler Support
*
* @ingroup RTEMSScoreCPUlm32
*
* @brief LatticeMicro32 (lm32) Assembler Support
*/
/**@{**/
#ifndef __USER_LABEL_PREFIX__
/**
* Recent versions of GNU cpp define variables which indicate the
* need for underscores and percents. If not using GNU cpp or
* the version does not support this, then you will obviously
* have to define these as appropriate.
*
* This symbol is prefixed to all C program symbols.
*/
#define __USER_LABEL_PREFIX__ _
#endif
#ifndef __REGISTER_PREFIX__
/**
* Recent versions of GNU cpp define variables which indicate the
* need for underscores and percents. If not using GNU cpp or
* the version does not support this, then you will obviously
* have to define these as appropriate.
*
* This symbol is prefixed to all register names.
*/
#define __REGISTER_PREFIX__
#endif
#include <rtems/concat.h>
/** Use the right prefix for global labels. */
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
/** Use the right prefix for registers. */
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
/*
* define macros for all of the registers on this CPU
*
* EXAMPLE: #define d0 REG (d0)
*/
/*
* Define macros to handle section beginning and ends.
*/
/** This macro is used to denote the beginning of a code declaration. */
#define BEGIN_CODE_DCL .text
/** This macro is used to denote the end of a code declaration. */
#define END_CODE_DCL
/** This macro is used to denote the beginning of a data declaration section. */
#define BEGIN_DATA_DCL .data
/** This macro is used to denote the end of a data declaration section. */
#define END_DATA_DCL
/** This macro is used to denote the beginning of a code section. */
#define BEGIN_CODE .text
/** This macro is used to denote the end of a code section. */
#define END_CODE
/** This macro is used to denote the beginning of a data section. */
#define BEGIN_DATA
/** This macro is used to denote the end of a data section. */
#define END_DATA
/**
* This macro is used to denote the beginning of the
* unitialized data section.
*/
#define BEGIN_BSS
/** This macro is used to denote the end of the unitialized data section. */
#define END_BSS
/** This macro is used to denote the end of the assembly file. */
#define END
/**
* This macro is used to declare a public global symbol.
*
* NOTE: This must be tailored for a particular flavor of the C compiler.
* They may need to put underscores in front of the symbols.
*/
#define PUBLIC(sym) .globl SYM (sym)
/**
* This macro is used to prototype a public global symbol.
*
* NOTE: This must be tailored for a particular flavor of the C compiler.
* They may need to put underscores in front of the symbols.
*/
#define EXTERN(sym) .globl SYM (sym)
/**@}**/
#endif

View File

@@ -1,755 +0,0 @@
/**
* @file
*
* @brief LM32 CPU Department Source
*
* This include file contains information pertaining to the LM32
* processor.
*/
/*
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef _RTEMS_SCORE_CPU_H
#define _RTEMS_SCORE_CPU_H
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems/score/basedefs.h>
#include <rtems/score/lm32.h>
/* conditional compilation parameters */
/**
* Does the CPU follow the simple vectored interrupt model?
*
* If TRUE, then RTEMS allocates the vector table it internally manages.
* If FALSE, then the BSP is assumed to allocate and manage the vector
* table
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_SIMPLE_VECTORED_INTERRUPTS TRUE
/**
* Does the RTEMS invoke the user's ISR with the vector number and
* a pointer to the saved interrupt frame (1) or just the vector
* number (0)?
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_ISR_PASSES_FRAME_POINTER TRUE
#define CPU_HARDWARE_FP FALSE
#define CPU_SOFTWARE_FP FALSE
/**
* Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
*
* If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
* If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
*
* So far, the only CPUs in which this option has been used are the
* HP PA-RISC and PowerPC. On the PA-RISC, The HP C compiler and
* gcc both implicitly used the floating point registers to perform
* integer multiplies. Similarly, the PowerPC port of gcc has been
* seen to allocate floating point local variables and touch the FPU
* even when the flow through a subroutine (like vfprintf()) might
* not use floating point formats.
*
* If a function which you would not think utilize the FP unit DOES,
* then one can not easily predict which tasks will use the FP hardware.
* In this case, this option should be TRUE.
*
* If @ref CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_ALL_TASKS_ARE_FP FALSE
/**
* Should the IDLE task have a floating point context?
*
* If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
* and it has a floating point context which is switched in and out.
* If FALSE, then the IDLE task does not have a floating point context.
*
* Setting this to TRUE negatively impacts the time required to preempt
* the IDLE task from an interrupt because the floating point context
* must be saved as part of the preemption.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_IDLE_TASK_IS_FP FALSE
/**
* Should the saving of the floating point registers be deferred
* until a context switch is made to another different floating point
* task?
*
* If TRUE, then the floating point context will not be stored until
* necessary. It will remain in the floating point registers and not
* disturned until another floating point task is switched to.
*
* If FALSE, then the floating point context is saved when a floating
* point task is switched out and restored when the next floating point
* task is restored. The state of the floating point registers between
* those two operations is not specified.
*
* If the floating point context does NOT have to be saved as part of
* interrupt dispatching, then it should be safe to set this to TRUE.
*
* Setting this flag to TRUE results in using a different algorithm
* for deciding when to save and restore the floating point context.
* The deferred FP switch algorithm minimizes the number of times
* the FP context is saved and restored. The FP context is not saved
* until a context switch is made to another, different FP task.
* Thus in a system with only one FP task, the FP context will never
* be saved or restored.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_USE_DEFERRED_FP_SWITCH TRUE
#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
/**
* Does the stack grow up (toward higher addresses) or down
* (toward lower addresses)?
*
* If TRUE, then the grows upward.
* If FALSE, then the grows toward smaller addresses.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_STACK_GROWS_UP FALSE
/* L2 cache lines are 32 bytes in Milkymist SoC */
#define CPU_CACHE_LINE_BYTES 32
#define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
/**
* @addtogroup RTEMSScoreCPUlm32Interrupt
* The following defines the number of bits actually used in the
* interrupt field of the task mode. How those bits map to the
* CPU interrupt levels is defined by the routine @ref _CPU_ISR_Set_level.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_MODES_INTERRUPT_MASK 0x00000001
#define CPU_MAXIMUM_PROCESSORS 32
/*
* Processor defined structures required for cpukit/score.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
/* may need to put some structures here. */
/**
* @defgroup RTEMSScoreCPUlm32Context Processor Dependent Context Management
*
* @ingroup RTEMSScoreCPUlm32
*
* From the highest level viewpoint, there are 2 types of context to save.
*
* -# Interrupt registers to save
* -# Task level registers to save
*
* Since RTEMS handles integer and floating point contexts separately, this
* means we have the following 3 context items:
*
* -# task level context stuff:: Context_Control
* -# floating point task stuff:: Context_Control_fp
* -# special interrupt level context :: CPU_Interrupt_frame
*
* On some processors, it is cost-effective to save only the callee
* preserved registers during a task context switch. This means
* that the ISR code needs to save those registers which do not
* persist across function calls. It is not mandatory to make this
* distinctions between the caller/callee saves registers for the
* purpose of minimizing context saved during task switch and on interrupts.
* If the cost of saving extra registers is minimal, simplicity is the
* choice. Save the same context on interrupt entry as for tasks in
* this case.
*
* Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
* care should be used in designing the context area.
*
* On some CPUs with hardware floating point support, the Context_Control_fp
* structure will not be used or it simply consist of an array of a
* fixed number of bytes. This is done when the floating point context
* is dumped by a "FP save context" type instruction and the format
* is not really defined by the CPU. In this case, there is no need
* to figure out the exact format -- only the size. Of course, although
* this is enough information for RTEMS, it is probably not enough for
* a debugger such as gdb. But that is another problem.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
/**@{**/
/**
* This defines the minimal set of integer and processor state registers
* that must be saved during a voluntary context switch from one thread
* to another.
*/
typedef struct {
uint32_t r11;
uint32_t r12;
uint32_t r13;
uint32_t r14;
uint32_t r15;
uint32_t r16;
uint32_t r17;
uint32_t r18;
uint32_t r19;
uint32_t r20;
uint32_t r21;
uint32_t r22;
uint32_t r23;
uint32_t r24;
uint32_t r25;
uint32_t gp;
uint32_t fp;
uint32_t sp;
uint32_t ra;
uint32_t ie;
uint32_t epc;
} Context_Control;
/**
*
* This macro returns the stack pointer associated with @a _context.
*
* @param[in] _context is the thread context area to access
*
* @return This method returns the stack pointer.
*/
#define _CPU_Context_Get_SP( _context ) \
(_context)->sp
/**
* This defines the set of integer and processor state registers that must
* be saved during an interrupt. This set does not include any which are
* in @ref Context_Control.
*/
typedef struct {
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t ra;
uint32_t ba;
uint32_t ea;
} CPU_Interrupt_frame;
/**
* This variable is optional. It is used on CPUs on which it is difficult
* to generate an "uninitialized" FP context. It is filled in by
* @ref _CPU_Initialize and copied into the task's FP context area during
* @ref _CPU_Context_Initialize.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#if 0
extern Context_Control_fp _CPU_Null_fp_context;
#endif
/** @} */
/**
* @defgroup RTEMSScoreCPUlm32Interrupt Processor Dependent Interrupt Management
*
* @ingroup RTEMSScoreCPUlm32
*/
/** @{ **/
/** @} **/
/*
* Nothing prevents the porter from declaring more CPU specific variables.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
/* XXX: if needed, put more variables here */
/**
* @addtogroup RTEMSScoreCPUlm32Interrupt
* Amount of extra stack (above minimum stack size) required by
* MPCI receive server thread. Remember that in a multiprocessor
* system this thread must exist and be able to process all directives.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
/**
* @addtogroup RTEMSScoreCPUlm32Interrupt
* This defines the number of entries in the @ref _ISR_Vector_table managed
* by RTEMS.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32
/**
* @addtogroup RTEMSScoreCPUlm32Interrupt
* This defines the highest interrupt vector number for this port.
*/
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/**
* @addtogroup RTEMSScoreCPUlm32Interrupt
* This is defined if the port has a special way to report the ISR nesting
* level. Most ports maintain the variable @a _ISR_Nest_level.
*/
#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
/**
* @addtogroup RTEMSScoreCPUlm32Context
* Should be large enough to run all RTEMS tests. This ensures
* that a "reasonable" small application should not have any problems.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_STACK_MINIMUM_SIZE (1024*4)
#define CPU_SIZEOF_POINTER 4
/**
* CPU's worst alignment requirement for data types on a byte boundary. This
* alignment does not take into account the requirements for the stack.
*
* Port Specific Information:
* The LM32 architecture manual simply states: "All memory accesses must be
* aligned to the size of the access", and there is no hardware support
* whatsoever for 64-bit numbers.
* (lm32_archman.pdf, July 2009, p. 15)
*/
#define CPU_ALIGNMENT 4
/**
* This number corresponds to the byte alignment requirement for the
* heap handler. This alignment requirement may be stricter than that
* for the data types alignment specified by @ref CPU_ALIGNMENT. It is
* common for the heap to follow the same alignment requirement as
* @ref CPU_ALIGNMENT. If the @ref CPU_ALIGNMENT is strict enough for
* the heap, then this should be set to @ref CPU_ALIGNMENT.
*
* NOTE: This does not have to be a power of 2 although it should be
* a multiple of 2 greater than or equal to 2. The requirement
* to be a multiple of 2 is because the heap uses the least
* significant field of the front and back flags to indicate
* that a block is in use or free. So you do not want any odd
* length blocks really putting length data in that bit.
*
* On byte oriented architectures, @ref CPU_HEAP_ALIGNMENT normally will
* have to be greater or equal to than @ref CPU_ALIGNMENT to ensure that
* elements allocated from the heap meet all restrictions.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
#define CPU_STACK_ALIGNMENT CPU_ALIGNMENT
#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
/*
* ISR handler macros
*/
/**
* @addtogroup RTEMSScoreCPUlm32Interrupt
*/
/**@{**/
/**
* Disable all interrupts for an RTEMS critical section. The previous
* level is returned in @a _isr_cookie.
*
* @param[out] _isr_cookie will contain the previous level cookie
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define _CPU_ISR_Disable( _isr_cookie ) \
lm32_disable_interrupts( _isr_cookie );
/**
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
* This indicates the end of an RTEMS critical section. The parameter
* @a _isr_cookie is not modified.
*
* @param[in] _isr_cookie contain the previous level cookie
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define _CPU_ISR_Enable( _isr_cookie ) \
lm32_enable_interrupts( _isr_cookie );
/**
* This temporarily restores the interrupt to @a _isr_cookie before immediately
* disabling them again. This is used to divide long RTEMS critical
* sections into two or more parts. The parameter @a _isr_cookie is not
* modified.
*
* @param[in] _isr_cookie contain the previous level cookie
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define _CPU_ISR_Flash( _isr_cookie ) \
lm32_flash_interrupts( _isr_cookie );
static inline bool _CPU_ISR_Is_enabled( uint32_t level )
{
return ( level & 0x0001 ) != 0;
}
/**
* This routine and @ref _CPU_ISR_Get_level
* Map the interrupt level in task mode onto the hardware that the CPU
* actually provides. Currently, interrupt levels which do not
* map onto the CPU in a generic fashion are undefined. Someday,
* it would be nice if these were "mapped" by the application
* via a callout. For example, m68k has 8 levels 0 - 7, levels
* 8 - 255 would be available for bsp/application specific meaning.
* This could be used to manage a programmable interrupt controller
* via the rtems_task_mode directive.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define _CPU_ISR_Set_level( new_level ) \
{ \
_CPU_ISR_Enable( ( new_level==0 ) ? 1 : 0 ); \
}
/**
* Return the current interrupt disable level for this task in
* the format used by the interrupt level portion of the task mode.
*
* NOTE: This routine usually must be implemented as a subroutine.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
uint32_t _CPU_ISR_Get_level( void );
/* end of ISR handler macros */
/** @} */
/* Context handler macros */
/**
* @addtogroup RTEMSScoreCPUlm32Context
* Initialize the context to a state suitable for starting a
* task after a context restore operation. Generally, this
* involves:
*
* - setting a starting address
* - preparing the stack
* - preparing the stack and frame pointers
* - setting the proper interrupt level in the context
* - initializing the floating point context
*
* This routine generally does not set any unnecessary register
* in the context. The state of the "general data" registers is
* undefined at task start time.
*
* @param[in] _the_context is the context structure to be initialized
* @param[in] _stack_base is the lowest physical address of this task's stack
* @param[in] _size is the size of this task's stack
* @param[in] _isr is the interrupt disable level
* @param[in] _entry_point is the thread's entry point. This is
* always @a _Thread_Handler
* @param[in] _is_fp is TRUE if the thread is to be a floating
* point thread. This is typically only used on CPUs where the
* FPU may be easily disabled by software such as on the SPARC
* where the PSR contains an enable FPU bit.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
extern char _gp[];
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point, _is_fp, _tls_area ) \
do { \
uint32_t _stack = (uint32_t)(_stack_base) + (_size) - 4; \
\
(void) _is_fp; /* avoid warning for being unused */ \
(void) _isr; /* avoid warning for being unused */ \
(_the_context)->gp = (uint32_t)_gp; \
(_the_context)->fp = (uint32_t)_stack; \
(_the_context)->sp = (uint32_t)_stack; \
(_the_context)->ra = (uint32_t)(_entry_point); \
} while ( 0 )
/**
* This routine is responsible for somehow restarting the currently
* executing task. If you are lucky, then all that is necessary
* is restoring the context. Otherwise, there will need to be
* a special assembly routine which does something special in this
* case. For many ports, simply adding a label to the restore path
* of @ref _CPU_Context_switch will work. On other ports, it may be
* possibly to load a few arguments and jump to the restore path. It will
* not work if restarting self conflicts with the stack frame
* assumptions of restoring a context.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define _CPU_Context_Restart_self( _the_context ) \
_CPU_Context_restore( (_the_context) );
/**
* This routine initializes the FP context area passed to it to.
* There are a few standard ways in which to initialize the
* floating point context. The code included for this macro assumes
* that this is a CPU in which a "initial" FP context was saved into
* @a _CPU_Null_fp_context and it simply copies it to the destination
* context passed to it.
*
* Other floating point context save/restore models include:
* -# not doing anything, and
* -# putting a "null FP status word" in the correct place in the FP context.
*
* @param[in] _destination is the floating point context area
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define _CPU_Context_Initialize_fp( _destination )
#if 0
{ \
*(*(_destination)) = _CPU_Null_fp_context; \
}
#endif
/* end of Context handler macros */
#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
#define CPU_USE_LIBC_INIT_FINI_ARRAY FALSE
/* functions */
/**
* This routine performs CPU dependent initialization.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_Initialize(void);
/**
* @addtogroup RTEMSScoreCPUlm32Interrupt
*/
/**@{**/
typedef void ( *CPU_ISR_raw_handler )( void );
static inline void _CPU_ISR_install_raw_handler(
uint32_t vector,
CPU_ISR_raw_handler new_handler,
CPU_ISR_raw_handler *old_handler
)
{
/* TODO */
}
typedef void ( *CPU_ISR_handler )( uint32_t );
void _CPU_ISR_install_vector(
uint32_t vector,
CPU_ISR_handler new_handler,
CPU_ISR_handler *old_handler
);
/** @} */
RTEMS_NO_RETURN void *_CPU_Thread_Idle_body( uintptr_t ignored );
/**
* @addtogroup RTEMSScoreCPUlm32Context
* This routine switches from the run context to the heir context.
*
* @param[in] run points to the context of the currently executing task
* @param[in] heir points to the context of the heir task
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_Context_switch(
Context_Control *run,
Context_Control *heir
);
/**
* @addtogroup RTEMSScoreCPUlm32Context
*/
/**@{**/
/**
* This routine is generally used only to restart self in an
* efficient manner. It may simply be a label in @ref _CPU_Context_switch.
*
* @param[in] new_context points to the context to be restored.
*
* NOTE: May be unnecessary to reload some registers.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
RTEMS_NO_RETURN void _CPU_Context_restore( Context_Control *new_context );
/** @} */
/* FIXME */
typedef CPU_Interrupt_frame CPU_Exception_frame;
void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
/**
* @defgroup RTEMSScoreCPUlm32CPUEndian CPUEndian
*
* @ingroup RTEMSScoreCPUlm32
*
* @brief CPUEndian
*/
/** @{ */
/**
* The following routine swaps the endian format of an unsigned int.
* It must be static because it is referenced indirectly.
*
* This version will work on any processor, but if there is a better
* way for your CPU PLEASE use it. The most common way to do this is to:
*
* swap least significant two bytes with 16-bit rotate
* swap upper and lower 16-bits
* swap most significant two bytes with 16-bit rotate
*
* Some CPUs have special instructions which swap a 32-bit quantity in
* a single instruction (e.g. i486). It is probably best to avoid
* an "endian swapping control bit" in the CPU. One good reason is
* that interrupts would probably have to be disabled to ensure that
* an interrupt does not try to access the same "chunk" with the wrong
* endian. Another good reason is that on some CPUs, the endian bit
* endianness for ALL fetches -- both code and data -- so the code
* will be fetched incorrectly.
*
* @param[in] value is the value to be swapped
* @return the value after being endian swapped
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
static inline uint32_t CPU_swap_u32(
uint32_t value
)
{
uint32_t byte1, byte2, byte3, byte4, swapped;
byte4 = (value >> 24) & 0xff;
byte3 = (value >> 16) & 0xff;
byte2 = (value >> 8) & 0xff;
byte1 = value & 0xff;
swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
return swapped;
}
/**
* This routine swaps a 16 bir quantity.
*
* @param[in] value is the value to be swapped
* @return the value after being endian swapped
*/
static inline uint16_t CPU_swap_u16(uint16_t v)
{
return v << 8 | v >> 8;
}
/** @} */
typedef uint32_t CPU_Counter_ticks;
uint32_t _CPU_Counter_frequency( void );
CPU_Counter_ticks _CPU_Counter_read( void );
/** Type that can store a 32-bit integer or a pointer. */
typedef uintptr_t CPU_Uint32ptr;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,74 +0,0 @@
/**
* @file
*
* @brief LM32 CPU Assembly File
*
* Very loose template for an include file for the cpu_asm.? file
* if it is implemented as a ".S" file (preprocessed by cpp) instead
* of a ".s" file (preprocessed by gm4 or gasp).
*/
/*
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
*/
#ifndef _RTEMS_SCORE_CPU_ASM_H
#define _RTEMS_SCORE_CPU_ASM_H
/* pull in the generated offsets */
/*
#include <rtems/score/offsets.h>
*/
/*
* Hardware General Registers
*/
/* put something here */
/*
* Hardware Floating Point Registers
*/
/* put something here */
/*
* Hardware Control Registers
*/
/* put something here */
/*
* Calling Convention
*/
/* put something here */
/*
* Temporary registers
*/
/* put something here */
/*
* Floating Point Registers - SW Conventions
*/
/* put something here */
/*
* Temporary floating point registers
*/
/* put something here */
#endif
/* end of file */

View File

@@ -1,88 +0,0 @@
/**
* @file
*
* @brief CPU Port Implementation API
*/
/*
* Copyright (c) 2013 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef _RTEMS_SCORE_CPUIMPL_H
#define _RTEMS_SCORE_CPUIMPL_H
#include <rtems/score/cpu.h>
/**
* @defgroup RTEMSScoreCPUlm32 LatticeMicro32 (lm32)
*
* @ingroup RTEMSScoreCPU
*
* @brief LatticeMicro32 (lm32) Architecture Support
*/
/** @{ */
#define CPU_PER_CPU_CONTROL_SIZE 0
#define CPU_THREAD_LOCAL_STORAGE_VARIANT 10
#ifndef ASM
#ifdef __cplusplus
extern "C" {
#endif
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
(void) pattern;
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
(void) pattern;
while (1) {
/* TODO */
}
}
static inline void _CPU_Instruction_illegal( void )
{
__asm__ volatile ( ".word 0" );
}
static inline void _CPU_Instruction_no_operation( void )
{
__asm__ volatile ( "nop" );
}
static inline void _CPU_Use_thread_local_storage(
const Context_Control *context
)
{
(void) context;
}
static inline void *_CPU_Get_TLS_thread_pointer(
const Context_Control *context
)
{
(void) context;
return NULL;
}
#ifdef __cplusplus
}
#endif
#endif /* ASM */
#endif /* _RTEMS_SCORE_CPUIMPL_H */
/** @} */

View File

@@ -1,112 +0,0 @@
/**
* @file
*
* @brief LM32 Set up Basic CPU Dependency Settings Based on Compiler Settings
*
* This file sets up basic CPU dependency settings based on
* compiler settings. For example, it can determine if
* floating point is available. This particular implementation
* is specified to the NO CPU port.
*/
/*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
* Micro-Research Finland Oy
*/
#ifndef _RTEMS_SCORE_LM32_H
#define _RTEMS_SCORE_LM32_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* This file contains the information required to build
* RTEMS for a particular member of the NO CPU family.
* It does this by setting variables to indicate which
* implementation dependent features are present in a particular
* member of the family.
*
* This is a good place to list all the known CPU models
* that this port supports and which RTEMS CPU model they correspond
* to.
*/
#if defined(rtems_multilib)
/*
* Figure out all CPU Model Feature Flags based upon compiler
* predefines.
*/
#define CPU_MODEL_NAME "rtems_multilib"
#define LM32_HAS_FPU 0
#elif defined(__lm32__)
#define CPU_MODEL_NAME "lm32"
#define LM32_HAS_FPU 0
#else
#error "Unsupported CPU Model"
#endif
/*
* Define the name of the CPU family.
*/
#define CPU_NAME "LM32"
#ifdef __cplusplus
}
#endif
#define lm32_read_interrupts( _ip) \
__asm__ volatile ("rcsr %0, ip":"=r"(_ip));
#define lm32_disable_interrupts( _level ) \
do { uint32_t ie; \
__asm__ volatile ("rcsr %0,ie":"=r"(ie)); \
(_level) = ie; \
ie &= (~0x0001); \
__asm__ volatile ("wcsr ie,%0"::"r"(ie)); \
} while (0)
#define lm32_enable_interrupts( _level ) \
__asm__ volatile ("wcsr ie,%0"::"r"(_level));
#define lm32_flash_interrupts( _level ) \
do { uint32_t ie; \
__asm__ volatile ("wcsr ie,%0"::"r"(_level)); \
ie = (_level) & (~0x0001); \
__asm__ volatile ("wcsr ie,%0"::"r"(ie)); \
} while (0)
#define lm32_interrupt_unmask( _mask ) \
do { uint32_t im; \
__asm__ volatile ("rcsr %0,im":"=r"(im)); \
im |= _mask; \
__asm__ volatile ("wcsr im,%0"::"r"(im)); \
} while (0)
#define lm32_interrupt_mask( _mask ) \
do { uint32_t im; \
__asm__ volatile ("rcsr %0,im":"=r"(im)); \
im &= ~(_mask); \
__asm__ volatile ("wcsr im,%0"::"r"(im)); \
} while (0)
#define lm32_interrupt_ack( _mask ) \
do { uint32_t ip = _mask; \
__asm__ volatile ("wcsr ip,%0"::"r"(ip)); \
} while (0)
#endif /* _RTEMS_SCORE_LM32_H */

View File

@@ -1,84 +0,0 @@
/**
* @file
*
* @brief LM32 Initialize the ISR Handler
*/
/*
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/isr.h>
#include <rtems/score/percpu.h>
#include <rtems/score/threaddispatch.h>
unsigned long *_old_stack_ptr;
void *_exception_stack_frame;
register unsigned long *stack_ptr __asm__ ("sp");
/*
* Prototypes for routines called from assembly that we don't want in
* the public name space.
*/
void __ISR_Handler(uint32_t vector, CPU_Interrupt_frame *ifr);
void __ISR_Handler(uint32_t vector, CPU_Interrupt_frame *ifr)
{
register uint32_t level;
_exception_stack_frame = NULL;
/* Interrupts are disabled upon entry to this Handler */
_Thread_Dispatch_disable();
if ( _ISR_Nest_level == 0 ) {
/* Install irq stack */
_old_stack_ptr = stack_ptr;
stack_ptr = _CPU_Interrupt_stack_high - 4;
}
_ISR_Nest_level++;
if ( _ISR_Vector_table[ vector] )
{
(*_ISR_Vector_table[ vector ])(vector, ifr);
};
/* Make sure that interrupts are disabled again */
_CPU_ISR_Disable( level );
_ISR_Nest_level--;
if( _ISR_Nest_level == 0)
stack_ptr = _old_stack_ptr;
_Thread_Dispatch_unnest( _Per_CPU_Get() );
_CPU_ISR_Enable( level );
if ( _ISR_Nest_level )
return;
if ( _Thread_Dispatch_necessary && _Thread_Dispatch_is_enabled() ) {
/* save off our stack frame so the context switcher can get to it */
_exception_stack_frame = ifr;
_Thread_Dispatch();
/* and make sure its clear in case we didn't dispatch. if we did, its
* already cleared */
_exception_stack_frame = NULL;
}
}

View File

@@ -1,18 +0,0 @@
/*
* Copyright (c) 2012 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/cpu.h>
void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
{
/* TODO */
}

View File

@@ -1,31 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
build-type: group
cflags: []
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
cppflags: []
cxxflags: []
enabled-by: true
includes: []
install:
- destination: ${BSP_INCLUDEDIR}/bsp
source:
- bsps/lm32/include/bsp/irq.h
- bsps/lm32/include/bsp/milkymist_ac97.h
- bsps/lm32/include/bsp/milkymist_buttons.h
- bsps/lm32/include/bsp/milkymist_dmx.h
- bsps/lm32/include/bsp/milkymist_flash.h
- bsps/lm32/include/bsp/milkymist_gpio.h
- bsps/lm32/include/bsp/milkymist_ir.h
- bsps/lm32/include/bsp/milkymist_memcard.h
- bsps/lm32/include/bsp/milkymist_midi.h
- bsps/lm32/include/bsp/milkymist_pfpu.h
- bsps/lm32/include/bsp/milkymist_tmu.h
- bsps/lm32/include/bsp/milkymist_usbinput.h
- bsps/lm32/include/bsp/milkymist_versions.h
- bsps/lm32/include/bsp/milkymist_video.h
ldflags: []
links: []
type: build
use-after: []
use-before: []

View File

@@ -1,17 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-string: null
- split: null
- env-append: null
build-type: option
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
default:
- enabled-by: true
value: []
description: |
ABI flags
enabled-by: true
links: []
name: ABI_FLAGS
type: build

View File

@@ -1,21 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
arch: lm32
bsp: lm32_evr_gdbsim
build-type: bsp
cflags: []
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
cppflags: []
enabled-by: true
family: lm32_evr
includes: []
install: []
links:
- role: build-dependency
uid: ../../opto2
- role: build-dependency
uid: ../../tstnointrcrit
- role: build-dependency
uid: grp
source: []
type: build

View File

@@ -1,19 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
arch: lm32
bsp: lm32_evr
build-type: bsp
cflags: []
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
cppflags: []
enabled-by: true
family: lm32_evr
includes: []
install: []
links:
- role: build-dependency
uid: ../../opto2
- role: build-dependency
uid: grp
source: []
type: build

View File

@@ -1,33 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
build-type: group
cflags: []
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
cppflags: []
cxxflags: []
enabled-by: true
includes: []
install: []
ldflags: []
links:
- role: build-dependency
uid: ../grp
- role: build-dependency
uid: abi
- role: build-dependency
uid: obj
- role: build-dependency
uid: optsim
- role: build-dependency
uid: ../start
- role: build-dependency
uid: ../../obj
- role: build-dependency
uid: ../../objirqdflt
- role: build-dependency
uid: ../../objmem
- role: build-dependency
uid: ../../bspopts
type: build
use-after: []
use-before: []

View File

@@ -1,31 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
build-type: objects
cflags: []
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
cppflags: []
cxxflags: []
enabled-by: true
includes: []
install:
- destination: ${BSP_INCLUDEDIR}
source:
- bsps/lm32/lm32_evr/include/bsp.h
- bsps/lm32/lm32_evr/include/system_conf.h
- destination: ${BSP_LIBDIR}
source:
- bsps/lm32/lm32_evr/start/linkcmds
links: []
source:
- bsps/lm32/shared/btimer/btimer.c
- bsps/lm32/shared/clock/ckinit.c
- bsps/lm32/shared/console/console.c
- bsps/lm32/shared/console/uart.c
- bsps/lm32/shared/start/bspreset.c
- bsps/lm32/shared/start/bspstart.c
- bsps/shared/cache/nocache.c
- bsps/shared/dev/getentropy/getentropy-cpucounter.c
- bsps/shared/start/gettargethash-default.c
- bsps/shared/start/sbrk.c
- bsps/shared/start/setvec.c
type: build

View File

@@ -1,18 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-boolean: null
- define-condition: null
build-type: option
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
default:
- enabled-by: lm32/lm32_evr_gdbsim
value: true
- enabled-by: true
value: false
description: |
If defined, this indicates the BSP is being built to run on the lm32 simulator in GDB. This enables fast idle support which speeds up the clock ticks while the idle task is running so time spent in the idle task is minimized. This significantly reduces the wall time required to execute the RTEMS test suites. It also enables a special exit and alternate printk support.
enabled-by: true
links: []
name: LM32_ON_SIMULATOR
type: build

View File

@@ -1,21 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-string: null
- split: null
- env-append: null
build-type: option
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
default:
- enabled-by: true
value:
- -mbarrel-shift-enabled
- -mmultiply-enabled
- -mdivide-enabled
- -msign-extend-enabled
description: |
ABI flags
enabled-by: true
links: []
name: ABI_FLAGS
type: build

View File

@@ -1,65 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
arch: lm32
bsp: milkymist
build-type: bsp
cflags: []
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
cppflags: []
enabled-by: true
family: milkymist
includes: []
install:
- destination: ${BSP_INCLUDEDIR}
source:
- bsps/lm32/milkymist/include/bsp.h
- bsps/lm32/milkymist/include/system_conf.h
- destination: ${BSP_LIBDIR}
source:
- bsps/lm32/milkymist/start/linkcmds
links:
- role: build-dependency
uid: ../grp
- role: build-dependency
uid: abi
- role: build-dependency
uid: optsim
- role: build-dependency
uid: ../start
- role: build-dependency
uid: ../../obj
- role: build-dependency
uid: ../../objirqdflt
- role: build-dependency
uid: ../../objmem
- role: build-dependency
uid: ../../opto2
- role: build-dependency
uid: ../../bspopts
source:
- bsps/lm32/milkymist/start/bspclean.c
- bsps/lm32/shared/irq/irq.c
- bsps/lm32/shared/milkymist_ac97/ac97.c
- bsps/lm32/shared/milkymist_buttons/buttons.c
- bsps/lm32/shared/milkymist_clock/ckinit.c
- bsps/lm32/shared/milkymist_console/console.c
- bsps/lm32/shared/milkymist_console/uart.c
- bsps/lm32/shared/milkymist_dmx/dmx.c
- bsps/lm32/shared/milkymist_flash/flash.c
- bsps/lm32/shared/milkymist_framebuffer/framebuffer.c
- bsps/lm32/shared/milkymist_gpio/gpio.c
- bsps/lm32/shared/milkymist_ir/ir.c
- bsps/lm32/shared/milkymist_memcard/memcard.c
- bsps/lm32/shared/milkymist_midi/midi.c
- bsps/lm32/shared/milkymist_pfpu/pfpu.c
- bsps/lm32/shared/milkymist_timer/timer.c
- bsps/lm32/shared/milkymist_tmu/tmu.c
- bsps/lm32/shared/milkymist_usbinput/usbinput.c
- bsps/lm32/shared/milkymist_versions/versions.c
- bsps/lm32/shared/milkymist_video/video.c
- bsps/lm32/shared/start/bspstart.c
- bsps/shared/cache/nocache.c
- bsps/shared/dev/getentropy/getentropy-cpucounter.c
- bsps/shared/start/gettargethash-default.c
- bsps/shared/start/sbrk.c
type: build

View File

@@ -1,16 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-boolean: null
- define-condition: null
build-type: option
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
default:
- enabled-by: true
value: false
description: |
If defined, this indicates the BSP is being built to run on the lm32 simulator in GDB. This enables fast idle support which speeds up the clock ticks while the idle task is running so time spent in the idle task is minimized. This significantly reduces the wall time required to execute the RTEMS test suites. It also enables a special exit and alternate printk support.
enabled-by: true
links: []
name: LM32_ON_SIMULATOR
type: build

View File

@@ -1,14 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
asflags: []
build-type: start-file
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
cppflags: []
enabled-by: true
includes: []
install-path: ${BSP_LIBDIR}
links: []
source:
- bsps/lm32/shared/start/start.S
target: start.o
type: build

View File

@@ -1,32 +0,0 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
build-type: objects
cflags: []
copyrights:
- Copyright (C) 2020 embedded brains GmbH & Co. KG
cppflags: []
cxxflags: []
enabled-by:
- lm32
includes: []
install:
- destination: ${BSP_INCLUDEDIR}/machine
source:
- cpukit/score/cpu/lm32/include/machine/elf_machdep.h
- destination: ${BSP_INCLUDEDIR}/rtems
source:
- cpukit/score/cpu/lm32/include/rtems/asm.h
- destination: ${BSP_INCLUDEDIR}/rtems/score
source:
- cpukit/score/cpu/lm32/include/rtems/score/cpu.h
- cpukit/score/cpu/lm32/include/rtems/score/cpu_asm.h
- cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h
- cpukit/score/cpu/lm32/include/rtems/score/lm32.h
links: []
source:
- cpukit/score/cpu/lm32/cpu.c
- cpukit/score/cpu/lm32/cpu_asm.S
- cpukit/score/cpu/lm32/irq.c
- cpukit/score/cpu/lm32/lm32-exception-frame-print.c
- cpukit/score/cpu/no_cpu/cpucounterfrequency.c
- cpukit/score/cpu/no_cpu/cpucounterread.c
type: build

View File

@@ -486,8 +486,6 @@ links:
uid: cpuarm
- role: build-dependency
uid: cpui386
- role: build-dependency
uid: cpulm32
- role: build-dependency
uid: cpum68k
- role: build-dependency