diff options
Diffstat (limited to 'arch')
511 files changed, 34836 insertions, 424 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index dc81b34..78a35e9 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -109,3 +109,6 @@ config HAVE_CLK config HAVE_DMA_API_DEBUG bool + +config HAVE_DEFAULT_NO_SPIN_MUTEXES + bool diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig index 82428c2..f56837f 100644 --- a/arch/arm/configs/magician_defconfig +++ b/arch/arm/configs/magician_defconfig @@ -1183,7 +1183,11 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_SA1100=y # CONFIG_RTC_DRV_PXA is not set # CONFIG_DMADEVICES is not set -# CONFIG_REGULATOR is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +CONFIG_REGULATOR_BQ24022=y # CONFIG_UIO is not set # CONFIG_STAGING is not set diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h index c10d1aa..ada93a8 100644 --- a/arch/arm/include/asm/sizes.h +++ b/arch/arm/include/asm/sizes.h @@ -32,6 +32,7 @@ #define SZ_4K 0x00001000 #define SZ_8K 0x00002000 #define SZ_16K 0x00004000 +#define SZ_32K 0x00008000 #define SZ_64K 0x00010000 #define SZ_128K 0x00020000 #define SZ_256K 0x00040000 diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 793fe7b..e6afff8 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -87,7 +87,7 @@ extern void __init at91_add_device_eth(struct at91_eth_data *data); /* USB Host */ struct at91_usbh_data { u8 ports; /* number of ports on root hub */ - u8 vbus_pin[]; /* port power-control pin */ + u8 vbus_pin[2]; /* port power-control pin */ }; extern void __init at91_add_device_usbh(struct at91_usbh_data *data); diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index dafe4f7..336e51d 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -590,27 +590,28 @@ static void omap1_init_ext_clk(struct clk * clk) static int omap1_clk_enable(struct clk *clk) { int ret = 0; + if (clk->usecount++ == 0) { - if (likely(clk->parent)) { + if (clk->parent) { ret = omap1_clk_enable(clk->parent); - - if (unlikely(ret != 0)) { - clk->usecount--; - return ret; - } + if (ret) + goto err; if (clk->flags & CLOCK_NO_IDLE_PARENT) omap1_clk_deny_idle(clk->parent); } ret = clk->ops->enable(clk); - - if (unlikely(ret != 0) && clk->parent) { - omap1_clk_disable(clk->parent); - clk->usecount--; + if (ret) { + if (clk->parent) + omap1_clk_disable(clk->parent); + goto err; } } + return ret; +err: + clk->usecount--; return ret; } diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index fc74e91..34a56a1 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -131,14 +131,14 @@ static struct musb_hdrc_platform_data musb_plat = { .power = 50, /* up to 100 mA */ }; -static u64 musb_dmamask = DMA_32BIT_MASK; +static u64 musb_dmamask = DMA_BIT_MASK(32); static struct platform_device musb_device = { .name = "musb_hdrc", .id = -1, .dev = { .dma_mask = &musb_dmamask, - .coherent_dma_mask = DMA_32BIT_MASK, + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = &musb_plat, }, .num_resources = ARRAY_SIZE(musb_resources), @@ -146,14 +146,14 @@ static struct platform_device musb_device = { }; #ifdef CONFIG_NOP_USB_XCEIV -static u64 nop_xceiv_dmamask = DMA_32BIT_MASK; +static u64 nop_xceiv_dmamask = DMA_BIT_MASK(32); static struct platform_device nop_xceiv_device = { .name = "nop_usb_xceiv", .id = -1, .dev = { .dma_mask = &nop_xceiv_dmamask, - .coherent_dma_mask = DMA_32BIT_MASK, + .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = NULL, }, }; diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 96a2006..3e66d90 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -343,6 +343,15 @@ config ARCH_PXA_PALM bool "PXA based Palm PDAs" select HAVE_PWM +config MACH_PALMTE2 + bool "Palm Tungsten|E2" + default y + depends on ARCH_PXA_PALM + select PXA25x + help + Say Y here if you intend to run this kernel on a Palm Tungsten|E2 + handheld computer. + config MACH_PALMT5 bool "Palm Tungsten|T5" default y diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c80e1ba..682dbf4 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_MACH_E740) += e740.o obj-$(CONFIG_MACH_E750) += e750.o obj-$(CONFIG_MACH_E400) += e400.o obj-$(CONFIG_MACH_E800) += e800.o +obj-$(CONFIG_MACH_PALMTE2) += palmte2.o obj-$(CONFIG_MACH_PALMT5) += palmt5.o obj-$(CONFIG_MACH_PALMTX) += palmtx.o obj-$(CONFIG_MACH_PALMLD) += palmld.o diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index 117b5435f..b50ef39 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -121,7 +121,7 @@ static inline void cmx2xx_init_dm9000(void) {} /* UCB1400 touchscreen controller */ #if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) static struct platform_device cmx2xx_ts_device = { - .name = "ucb1400_ts", + .name = "ucb1400_core", .id = -1, }; diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c index 10c2eaf..7c9c34c 100644 --- a/arch/arm/mach-pxa/colibri-pxa300.c +++ b/arch/arm/mach-pxa/colibri-pxa300.c @@ -15,7 +15,7 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/gpio.h> -#include <net/ax88796.h> +#include <linux/interrupt.h> #include <asm/mach-types.h> #include <asm/sizes.h> @@ -32,12 +32,13 @@ #if defined(CONFIG_AX88796) #define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO26_GPIO) + /* * Asix AX88796 Ethernet */ static struct ax_plat_data colibri_asix_platdata = { - .flags = AXFLG_MAC_FROMDEV, - .wordlength = 2 + .flags = 0, /* defined later */ + .wordlength = 2, }; static struct resource colibri_asix_resource[] = { @@ -49,7 +50,7 @@ static struct resource colibri_asix_resource[] = { [1] = { .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), - .flags = IORESOURCE_IRQ + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, } }; @@ -70,8 +71,8 @@ static mfp_cfg_t colibri_pxa300_eth_pin_config[] __initdata = { static void __init colibri_pxa300_init_eth(void) { + colibri_pxa3xx_init_eth(&colibri_asix_platdata); pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_eth_pin_config)); - set_irq_type(gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), IRQ_TYPE_EDGE_FALLING); platform_device_register(&asix_device); } #else diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c index 55b74a7..a18d37b 100644 --- a/arch/arm/mach-pxa/colibri-pxa320.c +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -15,7 +15,7 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/gpio.h> -#include <net/ax88796.h> +#include <linux/interrupt.h> #include <asm/mach-types.h> #include <asm/sizes.h> @@ -38,8 +38,8 @@ * Asix AX88796 Ethernet */ static struct ax_plat_data colibri_asix_platdata = { - .flags = AXFLG_MAC_FROMDEV, - .wordlength = 2 + .flags = 0, /* defined later */ + .wordlength = 2, }; static struct resource colibri_asix_resource[] = { @@ -51,7 +51,7 @@ static struct resource colibri_asix_resource[] = { [1] = { .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), - .flags = IORESOURCE_IRQ + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, } }; @@ -72,8 +72,8 @@ static mfp_cfg_t colibri_pxa320_eth_pin_config[] __initdata = { static void __init colibri_pxa320_init_eth(void) { + colibri_pxa3xx_init_eth(&colibri_asix_platdata); pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_eth_pin_config)); - set_irq_type(gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), IRQ_TYPE_EDGE_FALLING); platform_device_register(&asix_device); } #else diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index 12d0afc..ea34e34 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -14,6 +14,7 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/gpio.h> +#include <linux/etherdevice.h> #include <asm/mach-types.h> #include <mach/hardware.h> #include <asm/sizes.h> @@ -28,6 +29,40 @@ #include "generic.h" #include "devices.h" +#if defined(CONFIG_AX88796) +#define ETHER_ADDR_LEN 6 +static u8 ether_mac_addr[ETHER_ADDR_LEN]; + +void __init colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data) +{ + int i; + u64 serial = ((u64) system_serial_high << 32) | system_serial_low; + + /* + * If the bootloader passed in a serial boot tag, which contains a + * valid ethernet MAC, pass it to the interface. Toradex ships the + * modules with their own bootloader which provides a valid MAC + * this way. + */ + + for (i = 0; i < ETHER_ADDR_LEN; i++) { + ether_mac_addr[i] = serial & 0xff; + serial >>= 8; + } + + if (is_valid_ether_addr(ether_mac_addr)) { + plat_data->flags |= AXFLG_MAC_FROMPLATFORM; + plat_data->mac_addr = ether_mac_addr; + printk(KERN_INFO "%s(): taking MAC from serial boot tag\n", + __func__); + } else { + plat_data->flags |= AXFLG_MAC_FROMDEV; + printk(KERN_INFO "%s(): no valid serial boot tag found, " + "taking MAC from device\n", __func__); + } +} +#endif + #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) static int mmc_detect_pin; diff --git a/arch/arm/mach-pxa/csb701.c b/arch/arm/mach-pxa/csb701.c index 4a2a295..5a221a4 100644 --- a/arch/arm/mach-pxa/csb701.c +++ b/arch/arm/mach-pxa/csb701.c @@ -5,6 +5,8 @@ #include <linux/input.h> #include <linux/leds.h> +#include <asm/mach-types.h> + static struct gpio_keys_button csb701_buttons[] = { { .code = 0x7, @@ -54,6 +56,9 @@ static struct platform_device *devices[] __initdata = { static int __init csb701_init(void) { + if (!machine_is_csb726()) + return -ENODEV; + return platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-pxa/e740.c b/arch/arm/mach-pxa/e740.c index 07500a0..a36fc17 100644 --- a/arch/arm/mach-pxa/e740.c +++ b/arch/arm/mach-pxa/e740.c @@ -29,6 +29,7 @@ #include <mach/udc.h> #include <mach/irda.h> #include <mach/irqs.h> +#include <mach/audio.h> #include "generic.h" #include "eseries.h" @@ -197,6 +198,7 @@ static void __init e740_init(void) eseries_get_tmio_gpios(); platform_add_devices(devices, ARRAY_SIZE(devices)); pxa_set_udc_info(&e7xx_udc_mach_info); + pxa_set_ac97_info(NULL); e7xx_irda_init(); pxa_set_ficp_info(&e7xx_ficp_platform_data); } diff --git a/arch/arm/mach-pxa/e750.c b/arch/arm/mach-pxa/e750.c index 6126c04..1d00110 100644 --- a/arch/arm/mach-pxa/e750.c +++ b/arch/arm/mach-pxa/e750.c @@ -28,6 +28,7 @@ #include <mach/udc.h> #include <mach/irda.h> #include <mach/irqs.h> +#include <mach/audio.h> #include "generic.h" #include "eseries.h" @@ -198,6 +199,7 @@ static void __init e750_init(void) eseries_get_tmio_gpios(); platform_add_devices(devices, ARRAY_SIZE(devices)); pxa_set_udc_info(&e7xx_udc_mach_info); + pxa_set_ac97_info(NULL); e7xx_irda_init(); pxa_set_ficp_info(&e7xx_ficp_platform_data); } diff --git a/arch/arm/mach-pxa/e800.c b/arch/arm/mach-pxa/e800.c index 74ab098..9866c7b 100644 --- a/arch/arm/mach-pxa/e800.c +++ b/arch/arm/mach-pxa/e800.c @@ -27,6 +27,7 @@ #include <mach/eseries-gpio.h> #include <mach/udc.h> #include <mach/irqs.h> +#include <mach/audio.h> #include "generic.h" #include "eseries.h" @@ -199,6 +200,7 @@ static void __init e800_init(void) eseries_get_tmio_gpios(); platform_add_devices(devices, ARRAY_SIZE(devices)); pxa_set_udc_info(&e800_udc_mach_info); + pxa_set_ac97_info(NULL); } MACHINE_START(E800, "Toshiba e800") diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 920dfb8..67611da 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -25,8 +25,10 @@ #include <linux/regulator/machine.h> #include <linux/spi/spi.h> #include <linux/spi/tdo24m.h> +#include <linux/spi/libertas_spi.h> #include <linux/power_supply.h> #include <linux/apm-emulation.h> +#include <linux/delay.h> #include <media/soc_camera.h> @@ -62,6 +64,8 @@ #define GPIO93_CAM_RESET (93) #define GPIO41_ETHIRQ (41) #define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) +#define GPIO115_WLAN_PWEN (115) +#define GPIO19_WLAN_STRAP (19) static int mmc_cd; static int nand_rb; @@ -159,8 +163,8 @@ static unsigned long common_pin_config[] = { GPIO57_SSP1_TXD, /* SSP2 */ - GPIO19_SSP2_SCLK, - GPIO14_SSP2_SFRM, + GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */ + GPIO14_GPIO, GPIO89_SSP2_TXD, GPIO88_SSP2_RXD, @@ -648,20 +652,86 @@ static struct tdo24m_platform_data em_x270_tdo24m_pdata = { .model = TDO35S, }; +static struct pxa2xx_spi_master em_x270_spi_2_info = { + .num_chipselect = 1, + .enable_dma = 1, +}; + +static struct pxa2xx_spi_chip em_x270_libertas_chip = { + .rx_threshold = 1, + .tx_threshold = 1, + .timeout = 1000, +}; + +static unsigned long em_x270_libertas_pin_config[] = { + /* SSP2 */ + GPIO19_SSP2_SCLK, + GPIO14_GPIO, + GPIO89_SSP2_TXD, + GPIO88_SSP2_RXD, +}; + +static int em_x270_libertas_setup(struct spi_device *spi) +{ + int err = gpio_request(GPIO115_WLAN_PWEN, "WLAN PWEN"); + if (err) + return err; + + gpio_direction_output(GPIO19_WLAN_STRAP, 1); + mdelay(100); + + pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_libertas_pin_config)); + + gpio_direction_output(GPIO115_WLAN_PWEN, 0); + mdelay(100); + gpio_set_value(GPIO115_WLAN_PWEN, 1); + mdelay(100); + + spi->bits_per_word = 16; + spi_setup(spi); + + return 0; +} + +static int em_x270_libertas_teardown(struct spi_device *spi) +{ + gpio_set_value(GPIO115_WLAN_PWEN, 0); + gpio_free(GPIO115_WLAN_PWEN); + + return 0; +} + +struct libertas_spi_platform_data em_x270_libertas_pdata = { + .use_dummy_writes = 1, + .gpio_cs = 14, + .setup = em_x270_libertas_setup, + .teardown = em_x270_libertas_teardown, +}; + static struct spi_board_info em_x270_spi_devices[] __initdata = { { - .modalias = "tdo24m", - .max_speed_hz = 1000000, - .bus_num = 1, - .chip_select = 0, - .controller_data = &em_x270_tdo24m_chip, - .platform_data = &em_x270_tdo24m_pdata, + .modalias = "tdo24m", + .max_speed_hz = 1000000, + .bus_num = 1, + .chip_select = 0, + .controller_data = &em_x270_tdo24m_chip, + .platform_data = &em_x270_tdo24m_pdata, + }, + { + .modalias = "libertas_spi", + .max_speed_hz = 13000000, + .bus_num = 2, + .irq = IRQ_GPIO(116), + .chip_select = 0, + .controller_data = &em_x270_libertas_chip, + .platform_data = &em_x270_libertas_pdata, }, }; static void __init em_x270_init_spi(void) { pxa2xx_set_spi_info(1, &em_x270_spi_info); + pxa2xx_set_spi_info(2, &em_x270_spi_2_info); spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices)); } #else diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h index 3f2a01d..90230c6 100644 --- a/arch/arm/mach-pxa/include/mach/colibri.h +++ b/arch/arm/mach-pxa/include/mach/colibri.h @@ -1,5 +1,8 @@ #ifndef _COLIBRI_H_ #define _COLIBRI_H_ + +#include <net/ax88796.h> + /* * common settings for all modules */ @@ -16,6 +19,10 @@ extern void colibri_pxa3xx_init_lcd(int bl_pin); static inline void colibri_pxa3xx_init_lcd(int) {} #endif +#if defined(CONFIG_AX88796) +extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data); +#endif + /* physical memory regions */ #define COLIBRI_SDRAM_BASE 0xa0000000 /* SDRAM region */ diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h index 82a399f..20ef37d 100644 --- a/arch/arm/mach-pxa/include/mach/magician.h +++ b/arch/arm/mach-pxa/include/mach/magician.h @@ -27,7 +27,7 @@ #define GPIO22_MAGICIAN_VIBRA_EN 22 #define GPIO26_MAGICIAN_GSM_POWER 26 #define GPIO27_MAGICIAN_USBC_PUEN 27 -#define GPIO30_MAGICIAN_nCHARGE_EN 30 +#define GPIO30_MAGICIAN_BQ24022_nCHARGE_EN 30 #define GPIO37_MAGICIAN_KEY_HANGUP 37 #define GPIO38_MAGICIAN_KEY_CONTACTS 38 #define GPIO40_MAGICIAN_GSM_OUT2 40 @@ -98,7 +98,7 @@ #define EGPIO_MAGICIAN_UNKNOWN_WAVEDEV_DLL MAGICIAN_EGPIO(2, 2) #define EGPIO_MAGICIAN_FLASH_VPP MAGICIAN_EGPIO(2, 3) #define EGPIO_MAGICIAN_BL_POWER2 MAGICIAN_EGPIO(2, 4) -#define EGPIO_MAGICIAN_CHARGE_EN MAGICIAN_EGPIO(2, 5) +#define EGPIO_MAGICIAN_BQ24022_ISET2 MAGICIAN_EGPIO(2, 5) #define EGPIO_MAGICIAN_GSM_POWER MAGICIAN_EGPIO(2, 7) /* input */ diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h index 7c295a4..fb13c82 100644 --- a/arch/arm/mach-pxa/include/mach/palmld.h +++ b/arch/arm/mach-pxa/include/mach/palmld.h @@ -87,6 +87,7 @@ #define PALMLD_IDE_SIZE 0x00100000 #define PALMLD_PHYS_IO_START 0x40000000 +#define PALMLD_STR_BASE 0xa0200000 /* BATTERY */ #define PALMLD_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */ diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h index 94db288..052bfe7 100644 --- a/arch/arm/mach-pxa/include/mach/palmt5.h +++ b/arch/arm/mach-pxa/include/mach/palmt5.h @@ -59,6 +59,7 @@ /* Various addresses */ #define PALMT5_PHYS_RAM_START 0xa0000000 #define PALMT5_PHYS_IO_START 0x40000000 +#define PALMT5_STR_BASE 0xa0200000 /* TOUCHSCREEN */ #define AC97_LINK_FRAME 21 diff --git a/arch/arm/mach-pxa/include/mach/palmte2.h b/arch/arm/mach-pxa/include/mach/palmte2.h new file mode 100644 index 0000000..1236134 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/palmte2.h @@ -0,0 +1,68 @@ +/* + * GPIOs and interrupts for Palm Tungsten|E2 Handheld Computer + * + * Author: + * Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef _INCLUDE_PALMTE2_H_ +#define _INCLUDE_PALMTE2_H_ + +/** HERE ARE GPIOs **/ + +/* GPIOs */ +#define GPIO_NR_PALMTE2_POWER_DETECT 9 +#define GPIO_NR_PALMTE2_HOTSYNC_BUTTON_N 4 +#define GPIO_NR_PALMTE2_EARPHONE_DETECT 15 + +/* SD/MMC */ +#define GPIO_NR_PALMTE2_SD_DETECT_N 10 +#define GPIO_NR_PALMTE2_SD_POWER 55 +#define GPIO_NR_PALMTE2_SD_READONLY 51 + +/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */ +#define GPIO_NR_PALMTE2_IR_DISABLE 48 + +/* USB */ +#define GPIO_NR_PALMTE2_USB_DETECT_N 35 +#define GPIO_NR_PALMTE2_USB_PULLUP 53 + +/* LCD/BACKLIGHT */ +#define GPIO_NR_PALMTE2_BL_POWER 56 +#define GPIO_NR_PALMTE2_LCD_POWER 37 + +/* KEYS */ +#define GPIO_NR_PALMTE2_KEY_NOTES 5 +#define GPIO_NR_PALMTE2_KEY_TASKS 7 +#define GPIO_NR_PALMTE2_KEY_CALENDAR 11 +#define GPIO_NR_PALMTE2_KEY_CONTACTS 13 +#define GPIO_NR_PALMTE2_KEY_CENTER 14 +#define GPIO_NR_PALMTE2_KEY_LEFT 19 +#define GPIO_NR_PALMTE2_KEY_RIGHT 20 +#define GPIO_NR_PALMTE2_KEY_DOWN 21 +#define GPIO_NR_PALMTE2_KEY_UP 22 + +/** HERE ARE INIT VALUES **/ + +/* BACKLIGHT */ +#define PALMTE2_MAX_INTENSITY 0xFE +#define PALMTE2_DEFAULT_INTENSITY 0x7E +#define PALMTE2_LIMIT_MASK 0x7F +#define PALMTE2_PRESCALER 0x3F +#define PALMTE2_PERIOD_NS 3500 + +/* BATTERY */ +#define PALMTE2_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ +#define PALMTE2_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ +#define PALMTE2_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMTE2_BAT_MIN_CURRENT 0 /* unknown */ +#define PALMTE2_BAT_MAX_CHARGE 1 /* unknown */ +#define PALMTE2_BAT_MIN_CHARGE 1 /* unknown */ +#define PALMTE2_MAX_LIFE_MINS 360 /* on-life in minutes */ + +#endif diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h index 1e8bccb..9f7d62f 100644 --- a/arch/arm/mach-pxa/include/mach/palmtx.h +++ b/arch/arm/mach-pxa/include/mach/palmtx.h @@ -78,6 +78,8 @@ #define PALMTX_PHYS_RAM_START 0xa0000000 #define PALMTX_PHYS_IO_START 0x40000000 +#define PALMTX_STR_BASE 0xa0200000 + #define PALMTX_PHYS_FLASH_START PXA_CS0_PHYS /* ChipSelect 0 */ #define PALMTX_PHYS_NAND_START PXA_CS1_PHYS /* ChipSelect 1 */ diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index deeea1c..c899bbd 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -25,6 +25,8 @@ #include <linux/mtd/physmap.h> #include <linux/pda_power.h> #include <linux/pwm_backlight.h> +#include <linux/regulator/bq24022.h> +#include <linux/regulator/machine.h> #include <linux/usb/gpio_vbus.h> #include <mach/hardware.h> @@ -552,33 +554,7 @@ static struct platform_device gpio_vbus = { static int power_supply_init(struct device *dev) { - int ret; - - ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC"); - if (ret) - goto err_cs_ac; - ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_USB, "CABLE_STATE_USB"); - if (ret) - goto err_cs_usb; - ret = gpio_request(EGPIO_MAGICIAN_CHARGE_EN, "CHARGE_EN"); - if (ret) - goto err_chg_en; - ret = gpio_request(GPIO30_MAGICIAN_nCHARGE_EN, "nCHARGE_EN"); - if (!ret) - ret = gpio_direction_output(GPIO30_MAGICIAN_nCHARGE_EN, 0); - if (ret) - goto err_nchg_en; - - return 0; - -err_nchg_en: - gpio_free(EGPIO_MAGICIAN_CHARGE_EN); -err_chg_en: - gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB); -err_cs_usb: - gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC); -err_cs_ac: - return ret; + return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC"); } static int magician_is_ac_online(void) @@ -586,22 +562,8 @@ static int magician_is_ac_online(void) return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC); } -static int magician_is_usb_online(void) -{ - return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_USB); -} - -static void magician_set_charge(int flags) -{ - gpio_set_value(GPIO30_MAGICIAN_nCHARGE_EN, !flags); - gpio_set_value(EGPIO_MAGICIAN_CHARGE_EN, flags); -} - static void power_supply_exit(struct device *dev) { - gpio_free(GPIO30_MAGICIAN_nCHARGE_EN); - gpio_free(EGPIO_MAGICIAN_CHARGE_EN); - gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB); gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC); } @@ -612,8 +574,6 @@ static char *magician_supplicants[] = { static struct pda_power_pdata power_supply_info = { .init = power_supply_init, .is_ac_online = magician_is_ac_online, - .is_usb_online = magician_is_usb_online, - .set_charge = magician_set_charge, .exit = power_supply_exit, .supplied_to = magician_supplicants, .num_supplicants = ARRAY_SIZE(magician_supplicants), @@ -646,6 +606,43 @@ static struct platform_device power_supply = { .num_resources = ARRAY_SIZE(power_supply_resources), }; +/* + * Battery charger + */ + +static struct regulator_consumer_supply bq24022_consumers[] = { + { + .dev = &gpio_vbus.dev, + .supply = "vbus_draw", + }, + { + .dev = &power_supply.dev, + .supply = "ac_draw", + }, +}; + +static struct regulator_init_data bq24022_init_data = { + .constraints = { + .max_uA = 500000, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT, + }, + .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), + .consumer_supplies = bq24022_consumers, +}; + +static struct bq24022_mach_info bq24022_info = { + .gpio_nce = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN, + .gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2, + .init_data = &bq24022_init_data, +}; + +static struct platform_device bq24022 = { + .name = "bq24022", + .id = -1, + .dev = { + .platform_data = &bq24022_info, + }, +}; /* * MMC/SD @@ -756,6 +753,7 @@ static struct platform_device *devices[] __initdata = { &egpio, &backlight, &pasic3, + &bq24022, &gpio_vbus, &power_supply, &strataflash, diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 97c93a7..9203b06 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -50,6 +50,7 @@ #include <mach/pxa27x-udc.h> #include <mach/i2c.h> #include <mach/camera.h> +#include <mach/audio.h> #include <media/soc_camera.h> #include <mach/mioa701.h> @@ -763,8 +764,6 @@ MIO_PARENT_DEV(mioa701_backlight, "pwm-backlight", &pxa27x_device_pwm0.dev, &mioa701_backlight_data); MIO_SIMPLE_DEV(mioa701_led, "leds-gpio", &gpio_led_info) MIO_SIMPLE_DEV(pxa2xx_pcm, "pxa2xx-pcm", NULL) -MIO_SIMPLE_DEV(pxa2xx_ac97, "pxa2xx-ac97", NULL) -MIO_PARENT_DEV(mio_wm9713_codec, "wm9713-codec", &pxa2xx_ac97.dev, NULL) MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL) MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL) MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data); @@ -774,8 +773,6 @@ static struct platform_device *devices[] __initdata = { &mioa701_backlight, &mioa701_led, &pxa2xx_pcm, - &pxa2xx_ac97, - &mio_wm9713_codec, &mioa701_sound, &power_dev, &strataflash, @@ -818,6 +815,7 @@ static void __init mioa701_machine_init(void) pxa_set_keypad_info(&mioa701_keypad_info); wm97xx_bat_set_pdata(&mioa701_battery_data); pxa_set_udc_info(&mioa701_udc_info); + pxa_set_ac97_info(NULL); pm_power_off = mioa701_poweroff; arm_pm_restart = mioa701_restart; platform_add_devices(devices, ARRAY_SIZE(devices)); diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 8587477..ecf5910 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -24,6 +24,7 @@ #include <linux/gpio.h> #include <linux/wm97xx_batt.h> #include <linux/power_supply.h> +#include <linux/sysdev.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -68,10 +69,10 @@ static unsigned long palmld_pin_config[] __initdata = { GPIO47_FICP_TXD, /* MATRIX KEYPAD */ - GPIO100_KP_MKIN_0, - GPIO101_KP_MKIN_1, - GPIO102_KP_MKIN_2, - GPIO97_KP_MKIN_3, + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, GPIO103_KP_MKOUT_0, GPIO104_KP_MKOUT_1, GPIO105_KP_MKOUT_2, @@ -507,6 +508,33 @@ static struct pxafb_mach_info palmld_lcd_screen = { }; /****************************************************************************** + * Power management - standby + ******************************************************************************/ +#ifdef CONFIG_PM +static u32 *addr __initdata; +static u32 resume[3] __initdata = { + 0xe3a00101, /* mov r0, #0x40000000 */ + 0xe380060f, /* orr r0, r0, #0x00f00000 */ + 0xe590f008, /* ldr pc, [r0, #0x08] */ +}; + +static int __init palmld_pm_init(void) +{ + int i; + + /* this is where the bootloader jumps */ + addr = phys_to_virt(PALMLD_STR_BASE); + + for (i = 0; i < 3; i++) + addr[i] = resume[i]; + + return 0; +} + +device_initcall(palmld_pm_init); +#endif + +/****************************************************************************** * Machine init ******************************************************************************/ static struct platform_device *devices[] __initdata = { diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 9521c7b..0680f1a 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -75,10 +75,10 @@ static unsigned long palmt5_pin_config[] __initdata = { GPIO95_GPIO, /* usb power */ /* MATRIX KEYPAD */ - GPIO100_KP_MKIN_0, - GPIO101_KP_MKIN_1, - GPIO102_KP_MKIN_2, - GPIO97_KP_MKIN_3, + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, GPIO103_KP_MKOUT_0, GPIO104_KP_MKOUT_1, GPIO105_KP_MKOUT_2, @@ -450,6 +450,33 @@ static struct pxafb_mach_info palmt5_lcd_screen = { }; /****************************************************************************** + * Power management - standby + ******************************************************************************/ +#ifdef CONFIG_PM +static u32 *addr __initdata; +static u32 resume[3] __initdata = { + 0xe3a00101, /* mov r0, #0x40000000 */ + 0xe380060f, /* orr r0, r0, #0x00f00000 */ + 0xe590f008, /* ldr pc, [r0, #0x08] */ +}; + +static int __init palmt5_pm_init(void) +{ + int i; + + /* this is where the bootloader jumps */ + addr = phys_to_virt(PALMT5_STR_BASE); + + for (i = 0; i < 3; i++) + addr[i] = resume[i]; + + return 0; +} + +device_initcall(palmt5_pm_init); +#endif + +/****************************************************************************** * Machine init ******************************************************************************/ static struct platform_device *devices[] __initdata = { diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c new file mode 100644 index 0000000..43fcf2e --- /dev/null +++ b/arch/arm/mach-pxa/palmte2.c @@ -0,0 +1,466 @@ +/* + * Hardware definitions for Palm Tungsten|E2 + * + * Author: + * Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com> + * + * Rewrite for mainline: + * Marek Vasut <marek.vasut@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * (find more info at www.hackndev.com) + * + */ + +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/pda_power.h> +#include <linux/pwm_backlight.h> +#include <linux/gpio.h> +#include <linux/wm97xx_batt.h> +#include <linux/power_supply.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/audio.h> +#include <mach/palmte2.h> +#include <mach/mmc.h> +#include <mach/pxafb.h> +#include <mach/mfp-pxa25x.h> +#include <mach/irda.h> +#include <mach/udc.h> + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long palmte2_pin_config[] __initdata = { + /* MMC */ + GPIO6_MMC_CLK, + GPIO8_MMC_CS0, + GPIO10_GPIO, /* SD detect */ + GPIO55_GPIO, /* SD power */ + GPIO51_GPIO, /* SD r/o switch */ + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* USB */ + GPIO15_GPIO, /* usb detect */ + GPIO53_GPIO, /* usb power */ + + /* IrDA */ + GPIO48_GPIO, /* ir disable */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* LCD */ + GPIO58_LCD_LDD_0, + GPIO59_LCD_LDD_1, + GPIO60_LCD_LDD_2, + GPIO61_LCD_LDD_3, + GPIO62_LCD_LDD_4, + GPIO63_LCD_LDD_5, + GPIO64_LCD_LDD_6, + GPIO65_LCD_LDD_7, + GPIO66_LCD_LDD_8, + GPIO67_LCD_LDD_9, + GPIO68_LCD_LDD_10, + GPIO69_LCD_LDD_11, + GPIO70_LCD_LDD_12, + GPIO71_LCD_LDD_13, + GPIO72_LCD_LDD_14, + GPIO73_LCD_LDD_15, + GPIO74_LCD_FCLK, + GPIO75_LCD_LCLK, + GPIO76_LCD_PCLK, + GPIO77_LCD_BIAS, + + /* GPIO KEYS */ + GPIO5_GPIO, /* notes */ + GPIO7_GPIO, /* tasks */ + GPIO11_GPIO, /* calendar */ + GPIO13_GPIO, /* contacts */ + GPIO14_GPIO, /* center */ + GPIO19_GPIO, /* left */ + GPIO20_GPIO, /* right */ + GPIO21_GPIO, /* down */ + GPIO22_GPIO, /* up */ + + /* MISC */ + GPIO1_RST, /* reset */ + GPIO4_GPIO, /* Hotsync button */ + GPIO9_GPIO, /* power detect */ + GPIO37_GPIO, /* LCD power */ + GPIO56_GPIO, /* Backlight power */ +}; + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +static int palmte2_mci_init(struct device *dev, + irq_handler_t palmte2_detect_int, void *data) +{ + int err = 0; + + /* Setup an interrupt for detecting card insert/remove events */ + err = gpio_request(GPIO_NR_PALMTE2_SD_DETECT_N, "SD IRQ"); + if (err) + goto err; + err = gpio_direction_input(GPIO_NR_PALMTE2_SD_DETECT_N); + if (err) + goto err2; + err = request_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), + palmte2_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM | + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "SD/MMC card detect", data); + if (err) { + printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n", + __func__); + goto err2; + } + + err = gpio_request(GPIO_NR_PALMTE2_SD_POWER, "SD_POWER"); + if (err) + goto err3; + err = gpio_direction_output(GPIO_NR_PALMTE2_SD_POWER, 0); + if (err) + goto err4; + + err = gpio_request(GPIO_NR_PALMTE2_SD_READONLY, "SD_READONLY"); + if (err) + goto err4; + err = gpio_direction_input(GPIO_NR_PALMTE2_SD_READONLY); + if (err) + goto err5; + + printk(KERN_DEBUG "%s: irq registered\n", __func__); + + return 0; + +err5: + gpio_free(GPIO_NR_PALMTE2_SD_READONLY); +err4: + gpio_free(GPIO_NR_PALMTE2_SD_POWER); +err3: + free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data); +err2: + gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N); +err: + return err; +} + +static void palmte2_mci_exit(struct device *dev, void *data) +{ + gpio_free(GPIO_NR_PALMTE2_SD_READONLY); + gpio_free(GPIO_NR_PALMTE2_SD_POWER); + free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data); + gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N); +} + +static void palmte2_mci_power(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data *p_d = dev->platform_data; + gpio_set_value(GPIO_NR_PALMTE2_SD_POWER, p_d->ocr_mask & (1 << vdd)); +} + +static int palmte2_mci_get_ro(struct device *dev) +{ + return gpio_get_value(GPIO_NR_PALMTE2_SD_READONLY); +} + +static struct pxamci_platform_data palmte2_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .setpower = palmte2_mci_power, + .get_ro = palmte2_mci_get_ro, + .init = palmte2_mci_init, + .exit = palmte2_mci_exit, +}; + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +static struct gpio_keys_button palmte2_pxa_buttons[] = { + {KEY_F1, GPIO_NR_PALMTE2_KEY_CONTACTS, 1, "Contacts" }, + {KEY_F2, GPIO_NR_PALMTE2_KEY_CALENDAR, 1, "Calendar" }, + {KEY_F3, GPIO_NR_PALMTE2_KEY_TASKS, 1, "Tasks" }, + {KEY_F4, GPIO_NR_PALMTE2_KEY_NOTES, 1, "Notes" }, + {KEY_ENTER, GPIO_NR_PALMTE2_KEY_CENTER, 1, "Center" }, + {KEY_LEFT, GPIO_NR_PALMTE2_KEY_LEFT, 1, "Left" }, + {KEY_RIGHT, GPIO_NR_PALMTE2_KEY_RIGHT, 1, "Right" }, + {KEY_DOWN, GPIO_NR_PALMTE2_KEY_DOWN, 1, "Down" }, + {KEY_UP, GPIO_NR_PALMTE2_KEY_UP, 1, "Up" }, +}; + +static struct gpio_keys_platform_data palmte2_pxa_keys_data = { + .buttons = palmte2_pxa_buttons, + .nbuttons = ARRAY_SIZE(palmte2_pxa_buttons), +}; + +static struct platform_device palmte2_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &palmte2_pxa_keys_data, + }, +}; + +/****************************************************************************** + * Backlight + ******************************************************************************/ +static int palmte2_backlight_init(struct device *dev) +{ + int ret; + + ret = gpio_request(GPIO_NR_PALMTE2_BL_POWER, "BL POWER"); + if (ret) + goto err; + ret = gpio_direction_output(GPIO_NR_PALMTE2_BL_POWER, 0); + if (ret) + goto err2; + ret = gpio_request(GPIO_NR_PALMTE2_LCD_POWER, "LCD POWER"); + if (ret) + goto err2; + ret = gpio_direction_output(GPIO_NR_PALMTE2_LCD_POWER, 0); + if (ret) + goto err3; + + return 0; +err3: + gpio_free(GPIO_NR_PALMTE2_LCD_POWER); +err2: + gpio_free(GPIO_NR_PALMTE2_BL_POWER); +err: + return ret; +} + +static int palmte2_backlight_notify(int brightness) +{ + gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness); + gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness); + return brightness; +} + +static void palmte2_backlight_exit(struct device *dev) +{ + gpio_free(GPIO_NR_PALMTE2_BL_POWER); + gpio_free(GPIO_NR_PALMTE2_LCD_POWER); +} + +static struct platform_pwm_backlight_data palmte2_backlight_data = { + .pwm_id = 0, + .max_brightness = PALMTE2_MAX_INTENSITY, + .dft_brightness = PALMTE2_MAX_INTENSITY, + .pwm_period_ns = PALMTE2_PERIOD_NS, + .init = palmte2_backlight_init, + .notify = palmte2_backlight_notify, + .exit = palmte2_backlight_exit, +}; + +static struct platform_device palmte2_backlight = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa25x_device_pwm0.dev, + .platform_data = &palmte2_backlight_data, + }, +}; + +/****************************************************************************** + * IrDA + ******************************************************************************/ +static int palmte2_irda_startup(struct device *dev) +{ + int err; + err = gpio_request(GPIO_NR_PALMTE2_IR_DISABLE, "IR DISABLE"); + if (err) + goto err; + err = gpio_direction_output(GPIO_NR_PALMTE2_IR_DISABLE, 1); + if (err) + gpio_free(GPIO_NR_PALMTE2_IR_DISABLE); +err: + return err; +} + +static void palmte2_irda_shutdown(struct device *dev) +{ + gpio_free(GPIO_NR_PALMTE2_IR_DISABLE); +} + +static void palmte2_irda_transceiver_mode(struct device *dev, int mode) +{ + gpio_set_value(GPIO_NR_PALMTE2_IR_DISABLE, mode & IR_OFF); + pxa2xx_transceiver_mode(dev, mode); +} + +static struct pxaficp_platform_data palmte2_ficp_platform_data = { + .startup = palmte2_irda_startup, + .shutdown = palmte2_irda_shutdown, + .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, + .transceiver_mode = palmte2_irda_transceiver_mode, +}; + +/****************************************************************************** + * UDC + ******************************************************************************/ +static struct pxa2xx_udc_mach_info palmte2_udc_info __initdata = { + .gpio_vbus = GPIO_NR_PALMTE2_USB_DETECT_N, + .gpio_vbus_inverted = 1, + .gpio_pullup = GPIO_NR_PALMTE2_USB_PULLUP, + .gpio_pullup_inverted = 0, +}; + +/****************************************************************************** + * Power supply + ******************************************************************************/ +static int power_supply_init(struct device *dev) +{ + int ret; + + ret = gpio_request(GPIO_NR_PALMTE2_POWER_DETECT, "CABLE_STATE_AC"); + if (ret) + goto err1; + ret = gpio_direction_input(GPIO_NR_PALMTE2_POWER_DETECT); + if (ret) + goto err2; + + return 0; + +err2: + gpio_free(GPIO_NR_PALMTE2_POWER_DETECT); +err1: + return ret; +} + +static int palmte2_is_ac_online(void) +{ + return gpio_get_value(GPIO_NR_PALMTE2_POWER_DETECT); +} + +static void power_supply_exit(struct device *dev) +{ + gpio_free(GPIO_NR_PALMTE2_POWER_DETECT); +} + +static char *palmte2_supplicants[] = { + "main-battery", +}; + +static struct pda_power_pdata power_supply_info = { + .init = power_supply_init, + .is_ac_online = palmte2_is_ac_online, + .exit = power_supply_exit, + .supplied_to = palmte2_supplicants, + .num_supplicants = ARRAY_SIZE(palmte2_supplicants), +}; + +static struct platform_device power_supply = { + .name = "pda-power", + .id = -1, + .dev = { + .platform_data = &power_supply_info, + }, +}; + +/****************************************************************************** + * WM97xx battery + ******************************************************************************/ +static struct wm97xx_batt_info wm97xx_batt_pdata = { + .batt_aux = WM97XX_AUX_ID3, + .temp_aux = WM97XX_AUX_ID2, + .charge_gpio = -1, + .max_voltage = PALMTE2_BAT_MAX_VOLTAGE, + .min_voltage = PALMTE2_BAT_MIN_VOLTAGE, + .batt_mult = 1000, + .batt_div = 414, + .temp_mult = 1, + .temp_div = 1, + .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO, + .batt_name = "main-batt", +}; + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +static struct pxafb_mode_info palmte2_lcd_modes[] = { +{ + .pixclock = 77757, + .xres = 320, + .yres = 320, + .bpp = 16, + + .left_margin = 28, + .right_margin = 7, + .upper_margin = 7, + .lower_margin = 5, + + .hsync_len = 4, + .vsync_len = 1, +}, +}; + +static struct pxafb_mach_info palmte2_lcd_screen = { + .modes = palmte2_lcd_modes, + .num_modes = ARRAY_SIZE(palmte2_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +}; + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static struct platform_device *devices[] __initdata = { +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + &palmte2_pxa_keys, +#endif + &palmte2_backlight, + &power_supply, +}; + +/* setup udc GPIOs initial state */ +static void __init palmte2_udc_init(void) +{ + if (!gpio_request(GPIO_NR_PALMTE2_USB_PULLUP, "UDC Vbus")) { + gpio_direction_output(GPIO_NR_PALMTE2_USB_PULLUP, 1); + gpio_free(GPIO_NR_PALMTE2_USB_PULLUP); + } +} + +static void __init palmte2_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(palmte2_pin_config)); + + set_pxa_fb_info(&palmte2_lcd_screen); + pxa_set_mci_info(&palmte2_mci_platform_data); + palmte2_udc_init(); + pxa_set_udc_info(&palmte2_udc_info); + pxa_set_ac97_info(NULL); + pxa_set_ficp_info(&palmte2_ficp_platform_data); + wm97xx_bat_set_pdata(&wm97xx_batt_pdata); + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +MACHINE_START(PALMTE2, "Palm Tungsten|E2") + .phys_io = 0x40000000, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .boot_params = 0xa0000100, + .map_io = pxa_map_io, + .init_irq = pxa25x_init_irq, + .timer = &pxa_timer, + .init_machine = palmte2_init +MACHINE_END diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index b490c09..59d0c1c 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -93,10 +93,10 @@ static unsigned long palmtx_pin_config[] __initdata = { GPIO116_GPIO, /* wifi ready */ /* MATRIX KEYPAD */ - GPIO100_KP_MKIN_0, - GPIO101_KP_MKIN_1, - GPIO102_KP_MKIN_2, - GPIO97_KP_MKIN_3, + GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, + GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, + GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, + GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, GPIO103_KP_MKOUT_0, GPIO104_KP_MKOUT_1, GPIO105_KP_MKOUT_2, @@ -459,6 +459,33 @@ static struct pxafb_mach_info palmtx_lcd_screen = { }; /****************************************************************************** + * Power management - standby + ******************************************************************************/ +#ifdef CONFIG_PM +static u32 *addr __initdata; +static u32 resume[3] __initdata = { + 0xe3a00101, /* mov r0, #0x40000000 */ + 0xe380060f, /* orr r0, r0, #0x00f00000 */ + 0xe590f008, /* ldr pc, [r0, #0x08] */ +}; + +static int __init palmtx_pm_init(void) +{ + int i; + + /* this is where the bootloader jumps */ + addr = phys_to_virt(PALMTX_STR_BASE); + + for (i = 0; i < 3; i++) + addr[i] = resume[i]; + + return 0; +} + +device_initcall(palmtx_pm_init); +#endif + +/****************************************************************************** * Machine init ******************************************************************************/ static struct platform_device *devices[] __initdata = { diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 6e8ade6..afac5b6 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -45,6 +45,7 @@ #include <mach/udc.h> #include <mach/tosa_bt.h> #include <mach/pxa2xx_spi.h> +#include <mach/audio.h> #include <asm/mach/arch.h> #include <mach/tosa.h> @@ -914,6 +915,7 @@ static void __init tosa_init(void) pxa_set_udc_info(&udc_info); pxa_set_ficp_info(&tosa_ficp_platform_data); pxa_set_i2c_info(NULL); + pxa_set_ac97_info(NULL); platform_scoop_config = &tosa_pcmcia_config; pxa2xx_set_spi_info(2, &pxa_ssp_master_info); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index b438fc4..e6344ec 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -828,6 +828,17 @@ void __init reserve_node_zero(pg_data_t *pgdat) BOOTMEM_DEFAULT); } + if (machine_is_palmld() || machine_is_palmtx()) { + reserve_bootmem_node(pgdat, 0xa0000000, 0x1000, + BOOTMEM_EXCLUSIVE); + reserve_bootmem_node(pgdat, 0xa0200000, 0x1000, + BOOTMEM_EXCLUSIVE); + } + + if (machine_is_palmt5()) + reserve_bootmem_node(pgdat, 0xa0200000, 0x1000, + BOOTMEM_EXCLUSIVE); + #ifdef CONFIG_SA1111 /* * Because of the SA1111 DMA bug, we want to preserve our diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild new file mode 100644 index 0000000..0f8956d --- /dev/null +++ b/arch/frv/include/asm/Kbuild @@ -0,0 +1,5 @@ +include include/asm-generic/Kbuild.asm + +header-y += registers.h + +unifdef-y += termios.h diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h new file mode 100644 index 0000000..296c35c --- /dev/null +++ b/arch/frv/include/asm/atomic.h @@ -0,0 +1,198 @@ +/* atomic.h: atomic operation emulation for FR-V + * + * For an explanation of how atomic ops work in this arch, see: + * Documentation/frv/atomic-ops.txt + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_ATOMIC_H +#define _ASM_ATOMIC_H + +#include <linux/types.h> +#include <asm/spr-regs.h> +#include <asm/system.h> + +#ifdef CONFIG_SMP +#error not SMP safe +#endif + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + * + * We do not have SMP systems, so we don't have to deal with that. + */ + +/* Atomic operations are already serializing */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#define ATOMIC_INIT(i) { (i) } +#define atomic_read(v) ((v)->counter) +#define atomic_set(v, i) (((v)->counter) = (i)) + +#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS +static inline int atomic_add_return(int i, atomic_t *v) +{ + unsigned long val; + + asm("0: \n" + " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */ + " ckeq icc3,cc7 \n" + " ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */ + " orcr cc7,cc7,cc3 \n" /* set CC3 to true */ + " add%I2 %1,%2,%1 \n" + " cst.p %1,%M0 ,cc3,#1 \n" + " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */ + " beq icc3,#0,0b \n" + : "+U"(v->counter), "=&r"(val) + : "NPr"(i) + : "memory", "cc7", "cc3", "icc3" + ); + + return val; +} + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + unsigned long val; + + asm("0: \n" + " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */ + " ckeq icc3,cc7 \n" + " ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */ + " orcr cc7,cc7,cc3 \n" /* set CC3 to true */ + " sub%I2 %1,%2,%1 \n" + " cst.p %1,%M0 ,cc3,#1 \n" + " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */ + " beq icc3,#0,0b \n" + : "+U"(v->counter), "=&r"(val) + : "NPr"(i) + : "memory", "cc7", "cc3", "icc3" + ); + + return val; +} + +#else + +extern int atomic_add_return(int i, atomic_t *v); +extern int atomic_sub_return(int i, atomic_t *v); + +#endif + +static inline int atomic_add_negative(int i, atomic_t *v) +{ + return atomic_add_return(i, v) < 0; +} + +static inline void atomic_add(int i, atomic_t *v) +{ + atomic_add_return(i, v); +} + +static inline void atomic_sub(int i, atomic_t *v) +{ + atomic_sub_return(i, v); +} + +static inline void atomic_inc(atomic_t *v) +{ + atomic_add_return(1, v); +} + +static inline void atomic_dec(atomic_t *v) +{ + atomic_sub_return(1, v); +} + +#define atomic_dec_return(v) atomic_sub_return(1, (v)) +#define atomic_inc_return(v) atomic_add_return(1, (v)) + +#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) +#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) + +/*****************************************************************************/ +/* + * exchange value with memory + */ +#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS + +#define xchg(ptr, x) \ +({ \ + __typeof__(ptr) __xg_ptr = (ptr); \ + __typeof__(*(ptr)) __xg_orig; \ + \ + switch (sizeof(__xg_orig)) { \ + case 4: \ + asm volatile( \ + "swap%I0 %M0,%1" \ + : "+m"(*__xg_ptr), "=r"(__xg_orig) \ + : "1"(x) \ + : "memory" \ + ); \ + break; \ + \ + default: \ + __xg_orig = (__typeof__(__xg_orig))0; \ + asm volatile("break"); \ + break; \ + } \ + \ + __xg_orig; \ +}) + +#else + +extern uint32_t __xchg_32(uint32_t i, volatile void *v); + +#define xchg(ptr, x) \ +({ \ + __typeof__(ptr) __xg_ptr = (ptr); \ + __typeof__(*(ptr)) __xg_orig; \ + \ + switch (sizeof(__xg_orig)) { \ + case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr); break; \ + default: \ + __xg_orig = (__typeof__(__xg_orig))0; \ + asm volatile("break"); \ + break; \ + } \ + __xg_orig; \ +}) + +#endif + +#define tas(ptr) (xchg((ptr), 1)) + +#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + +static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +{ + int c, old; + c = atomic_read(v); + for (;;) { + if (unlikely(c == (u))) + break; + old = atomic_cmpxchg((v), c, c + (a)); + if (likely(old == c)) + break; + c = old; + } + return c != (u); +} + +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + +#include <asm-generic/atomic.h> +#endif /* _ASM_ATOMIC_H */ diff --git a/arch/frv/include/asm/auxvec.h b/arch/frv/include/asm/auxvec.h new file mode 100644 index 0000000..0771077 --- /dev/null +++ b/arch/frv/include/asm/auxvec.h @@ -0,0 +1,4 @@ +#ifndef __FRV_AUXVEC_H +#define __FRV_AUXVEC_H + +#endif diff --git a/arch/frv/include/asm/ax88796.h b/arch/frv/include/asm/ax88796.h new file mode 100644 index 0000000..637e980 --- /dev/null +++ b/arch/frv/include/asm/ax88796.h @@ -0,0 +1,22 @@ +/* ax88796.h: access points to the driver for the AX88796 NE2000 clone + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_AX88796_H +#define _ASM_AX88796_H + +#include <asm/mb-regs.h> + +#define AX88796_IOADDR (__region_CS1 + 0x200) +#define AX88796_IRQ IRQ_CPU_EXTERNAL7 +#define AX88796_FULL_DUPLEX 0 /* force full duplex */ +#define AX88796_BUS_INFO "CS1#+0x200" /* bus info for ethtool */ + +#endif /* _ASM_AX88796_H */ diff --git a/arch/frv/include/asm/bitops.h b/arch/frv/include/asm/bitops.h new file mode 100644 index 0000000..287f6f6 --- /dev/null +++ b/arch/frv/include/asm/bitops.h @@ -0,0 +1,412 @@ +/* bitops.h: bit operations for the Fujitsu FR-V CPUs + * + * For an explanation of how atomic ops work in this arch, see: + * Documentation/frv/atomic-ops.txt + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_BITOPS_H +#define _ASM_BITOPS_H + +#include <linux/compiler.h> +#include <asm/byteorder.h> + +#ifdef __KERNEL__ + +#ifndef _LINUX_BITOPS_H +#error only <linux/bitops.h> can be included directly +#endif + +#include <asm-generic/bitops/ffz.h> + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS +static inline +unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v) +{ + unsigned long old, tmp; + + asm volatile( + "0: \n" + " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */ + " ckeq icc3,cc7 \n" + " ld.p %M0,%1 \n" /* LD.P/ORCR are atomic */ + " orcr cc7,cc7,cc3 \n" /* set CC3 to true */ + " and%I3 %1,%3,%2 \n" + " cst.p %2,%M0 ,cc3,#1 \n" /* if store happens... */ + " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* ... clear ICC3.Z */ + " beq icc3,#0,0b \n" + : "+U"(*v), "=&r"(old), "=r"(tmp) + : "NPr"(~mask) + : "memory", "cc7", "cc3", "icc3" + ); + + return old; +} + +static inline +unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v) +{ + unsigned long old, tmp; + + asm volatile( + "0: \n" + " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */ + " ckeq icc3,cc7 \n" + " ld.p %M0,%1 \n" /* LD.P/ORCR are atomic */ + " orcr cc7,cc7,cc3 \n" /* set CC3 to true */ + " or%I3 %1,%3,%2 \n" + " cst.p %2,%M0 ,cc3,#1 \n" /* if store happens... */ + " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* ... clear ICC3.Z */ + " beq icc3,#0,0b \n" + : "+U"(*v), "=&r"(old), "=r"(tmp) + : "NPr"(mask) + : "memory", "cc7", "cc3", "icc3" + ); + + return old; +} + +static inline +unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v) +{ + unsigned long old, tmp; + + asm volatile( + "0: \n" + " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */ + " ckeq icc3,cc7 \n" + " ld.p %M0,%1 \n" /* LD.P/ORCR are atomic */ + " orcr cc7,cc7,cc3 \n" /* set CC3 to true */ + " xor%I3 %1,%3,%2 \n" + " cst.p %2,%M0 ,cc3,#1 \n" /* if store happens... */ + " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* ... clear ICC3.Z */ + " beq icc3,#0,0b \n" + : "+U"(*v), "=&r"(old), "=r"(tmp) + : "NPr"(mask) + : "memory", "cc7", "cc3", "icc3" + ); + + return old; +} + +#else + +extern unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v); +extern unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v); +extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v); + +#endif + +#define atomic_clear_mask(mask, v) atomic_test_and_ANDNOT_mask((mask), (v)) +#define atomic_set_mask(mask, v) atomic_test_and_OR_mask((mask), (v)) + +static inline int test_and_clear_bit(int nr, volatile void *addr) +{ + volatile unsigned long *ptr = addr; + unsigned long mask = 1UL << (nr & 31); + ptr += nr >> 5; + return (atomic_test_and_ANDNOT_mask(mask, ptr) & mask) != 0; +} + +static inline int test_and_set_bit(int nr, volatile void *addr) +{ + volatile unsigned long *ptr = addr; + unsigned long mask = 1UL << (nr & 31); + ptr += nr >> 5; + return (atomic_test_and_OR_mask(mask, ptr) & mask) != 0; +} + +static inline int test_and_change_bit(int nr, volatile void *addr) +{ + volatile unsigned long *ptr = addr; + unsigned long mask = 1UL << (nr & 31); + ptr += nr >> 5; + return (atomic_test_and_XOR_mask(mask, ptr) & mask) != 0; +} + +static inline void clear_bit(int nr, volatile void *addr) +{ + test_and_clear_bit(nr, addr); +} + +static inline void set_bit(int nr, volatile void *addr) +{ + test_and_set_bit(nr, addr); +} + +static inline void change_bit(int nr, volatile void * addr) +{ + test_and_change_bit(nr, addr); +} + +static inline void __clear_bit(int nr, volatile void * addr) +{ + volatile unsigned long *a = addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 31); + *a &= ~mask; +} + +static inline void __set_bit(int nr, volatile void * addr) +{ + volatile unsigned long *a = addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 31); + *a |= mask; +} + +static inline void __change_bit(int nr, volatile void *addr) +{ + volatile unsigned long *a = addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 31); + *a ^= mask; +} + +static inline int __test_and_clear_bit(int nr, volatile void * addr) +{ + volatile unsigned long *a = addr; + int mask, retval; + + a += nr >> 5; + mask = 1 << (nr & 31); + retval = (mask & *a) != 0; + *a &= ~mask; + return retval; +} + +static inline int __test_and_set_bit(int nr, volatile void * addr) +{ + volatile unsigned long *a = addr; + int mask, retval; + + a += nr >> 5; + mask = 1 << (nr & 31); + retval = (mask & *a) != 0; + *a |= mask; + return retval; +} + +static inline int __test_and_change_bit(int nr, volatile void * addr) +{ + volatile unsigned long *a = addr; + int mask, retval; + + a += nr >> 5; + mask = 1 << (nr & 31); + retval = (mask & *a) != 0; + *a ^= mask; + return retval; +} + +/* + * This routine doesn't need to be atomic. + */ +static inline int __constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static inline int __test_bit(int nr, const volatile void * addr) +{ + int * a = (int *) addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + return ((mask & *a) != 0); +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + __constant_test_bit((nr),(addr)) : \ + __test_bit((nr),(addr))) + +#include <asm-generic/bitops/find.h> + +/** + * fls - find last bit set + * @x: the word to search + * + * This is defined the same way as ffs: + * - return 32..1 to indicate bit 31..0 most significant bit set + * - return 0 to indicate no bits set + */ +#define fls(x) \ +({ \ + int bit; \ + \ + asm(" subcc %1,gr0,gr0,icc0 \n" \ + " ckne icc0,cc4 \n" \ + " cscan.p %1,gr0,%0 ,cc4,#1 \n" \ + " csub %0,%0,%0 ,cc4,#0 \n" \ + " csub %2,%0,%0 ,cc4,#1 \n" \ + : "=&r"(bit) \ + : "r"(x), "r"(32) \ + : "icc0", "cc4" \ + ); \ + \ + bit; \ +}) + +/** + * fls64 - find last bit set in a 64-bit value + * @n: the value to search + * + * This is defined the same way as ffs: + * - return 64..1 to indicate bit 63..0 most significant bit set + * - return 0 to indicate no bits set + */ +static inline __attribute__((const)) +int fls64(u64 n) +{ + union { + u64 ll; + struct { u32 h, l; }; + } _; + int bit, x, y; + + _.ll = n; + + asm(" subcc.p %3,gr0,gr0,icc0 \n" + " subcc %4,gr0,gr0,icc1 \n" + " ckne icc0,cc4 \n" + " ckne icc1,cc5 \n" + " norcr cc4,cc5,cc6 \n" + " csub.p %0,%0,%0 ,cc6,1 \n" + " orcr cc5,cc4,cc4 \n" + " andcr cc4,cc5,cc4 \n" + " cscan.p %3,gr0,%0 ,cc4,0 \n" + " setlos #64,%1 \n" + " cscan.p %4,gr0,%0 ,cc4,1 \n" + " setlos #32,%2 \n" + " csub.p %1,%0,%0 ,cc4,0 \n" + " csub %2,%0,%0 ,cc4,1 \n" + : "=&r"(bit), "=r"(x), "=r"(y) + : "0r"(_.h), "r"(_.l) + : "icc0", "icc1", "cc4", "cc5", "cc6" + ); + return bit; + +} + +/** + * ffs - find first bit set + * @x: the word to search + * + * - return 32..1 to indicate bit 31..0 most least significant bit set + * - return 0 to indicate no bits set + */ +static inline __attribute__((const)) +int ffs(int x) +{ + /* Note: (x & -x) gives us a mask that is the least significant + * (rightmost) 1-bit of the value in x. + */ + return fls(x & -x); +} + +/** + * __ffs - find first bit set + * @x: the word to search + * + * - return 31..0 to indicate bit 31..0 most least significant bit set + * - if no bits are set in x, the result is undefined + */ +static inline __attribute__((const)) +int __ffs(unsigned long x) +{ + int bit; + asm("scan %1,gr0,%0" : "=r"(bit) : "r"(x & -x)); + return 31 - bit; +} + +/** + * __fls - find last (most-significant) set bit in a long word + * @word: the word to search + * + * Undefined if no set bit exists, so code should check against 0 first. + */ +static inline unsigned long __fls(unsigned long word) +{ + unsigned long bit; + asm("scan %1,gr0,%0" : "=r"(bit) : "r"(word)); + return bit; +} + +/* + * special slimline version of fls() for calculating ilog2_u32() + * - note: no protection against n == 0 + */ +#define ARCH_HAS_ILOG2_U32 +static inline __attribute__((const)) +int __ilog2_u32(u32 n) +{ + int bit; + asm("scan %1,gr0,%0" : "=r"(bit) : "r"(n)); + return 31 - bit; +} + +/* + * special slimline version of fls64() for calculating ilog2_u64() + * - note: no protection against n == 0 + */ +#define ARCH_HAS_ILOG2_U64 +static inline __attribute__((const)) +int __ilog2_u64(u64 n) +{ + union { + u64 ll; + struct { u32 h, l; }; + } _; + int bit, x, y; + + _.ll = n; + + asm(" subcc %3,gr0,gr0,icc0 \n" + " ckeq icc0,cc4 \n" + " cscan.p %3,gr0,%0 ,cc4,0 \n" + " setlos #63,%1 \n" + " cscan.p %4,gr0,%0 ,cc4,1 \n" + " setlos #31,%2 \n" + " csub.p %1,%0,%0 ,cc4,0 \n" + " csub %2,%0,%0 ,cc4,1 \n" + : "=&r"(bit), "=r"(x), "=r"(y) + : "0r"(_.h), "r"(_.l) + : "icc0", "cc4" + ); + return bit; +} + +#include <asm-generic/bitops/sched.h> +#include <asm-generic/bitops/hweight.h> +#include <asm-generic/bitops/lock.h> + +#include <asm-generic/bitops/ext2-non-atomic.h> + +#define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit ((nr) ^ 0x18, (addr)) +#define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr) ^ 0x18, (addr)) + +#include <asm-generic/bitops/minix-le.h> + +#endif /* __KERNEL__ */ + +#endif /* _ASM_BITOPS_H */ diff --git a/arch/frv/include/asm/bug.h b/arch/frv/include/asm/bug.h new file mode 100644 index 0000000..6b1b44d --- /dev/null +++ b/arch/frv/include/asm/bug.h @@ -0,0 +1,53 @@ +/* bug.h: FRV bug trapping + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_BUG_H +#define _ASM_BUG_H + +#include <linux/linkage.h> + +#ifdef CONFIG_BUG +/* + * Tell the user there is some problem. + */ +extern asmlinkage void __debug_bug_trap(int signr); + +#ifdef CONFIG_NO_KERNEL_MSG +#define _debug_bug_printk() +#else +extern void __debug_bug_printk(const char *file, unsigned line); +#define _debug_bug_printk() __debug_bug_printk(__FILE__, __LINE__) +#endif + +#define _debug_bug_trap(signr) \ +do { \ + __debug_bug_trap(signr); \ + asm volatile("nop"); \ +} while(0) + +#define HAVE_ARCH_BUG +#define BUG() \ +do { \ + _debug_bug_printk(); \ + _debug_bug_trap(6 /*SIGABRT*/); \ +} while (0) + +#ifdef CONFIG_GDBSTUB +#define HAVE_ARCH_KGDB_RAISE +#define kgdb_raise(signr) do { _debug_bug_trap(signr); } while(0) + +#define HAVE_ARCH_KGDB_BAD_PAGE +#define kgdb_bad_page(page) do { kgdb_raise(SIGABRT); } while(0) +#endif +#endif + +#include <asm-generic/bug.h> + +#endif diff --git a/arch/frv/include/asm/bugs.h b/arch/frv/include/asm/bugs.h new file mode 100644 index 0000000..f2382be --- /dev/null +++ b/arch/frv/include/asm/bugs.h @@ -0,0 +1,14 @@ +/* bugs.h: arch bug checking entry + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +static inline void check_bugs(void) +{ +} diff --git a/arch/frv/include/asm/busctl-regs.h b/arch/frv/include/asm/busctl-regs.h new file mode 100644 index 0000000..bb0ff48 --- /dev/null +++ b/arch/frv/include/asm/busctl-regs.h @@ -0,0 +1,41 @@ +/* busctl-regs.h: FR400-series CPU bus controller registers + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_BUSCTL_REGS_H +#define _ASM_BUSCTL_REGS_H + +/* bus controller registers */ +#define __get_LGCR() ({ *(volatile unsigned long *)(0xfe000010); }) +#define __get_LMAICR() ({ *(volatile unsigned long *)(0xfe000030); }) +#define __get_LEMBR() ({ *(volatile unsigned long *)(0xfe000040); }) +#define __get_LEMAM() ({ *(volatile unsigned long *)(0xfe000048); }) +#define __get_LCR(R) ({ *(volatile unsigned long *)(0xfe000100 + 8*(R)); }) +#define __get_LSBR(R) ({ *(volatile unsigned long *)(0xfe000c00 + 8*(R)); }) +#define __get_LSAM(R) ({ *(volatile unsigned long *)(0xfe000d00 + 8*(R)); }) + +#define __set_LGCR(V) do { *(volatile unsigned long *)(0xfe000010) = (V); } while(0) +#define __set_LMAICR(V) do { *(volatile unsigned long *)(0xfe000030) = (V); } while(0) +#define __set_LEMBR(V) do { *(volatile unsigned long *)(0xfe000040) = (V); } while(0) +#define __set_LEMAM(V) do { *(volatile unsigned long *)(0xfe000048) = (V); } while(0) +#define __set_LCR(R,V) do { *(volatile unsigned long *)(0xfe000100 + 8*(R)) = (V); } while(0) +#define __set_LSBR(R,V) do { *(volatile unsigned long *)(0xfe000c00 + 8*(R)) = (V); } while(0) +#define __set_LSAM(R,V) do { *(volatile unsigned long *)(0xfe000d00 + 8*(R)) = (V); } while(0) + +/* FR401 SDRAM controller registers */ +#define __get_DBR(R) ({ *(volatile unsigned long *)(0xfe000e00 + 8*(R)); }) +#define __get_DAM(R) ({ *(volatile unsigned long *)(0xfe000f00 + 8*(R)); }) + +/* FR551 SDRAM controller registers */ +#define __get_DARS(R) ({ *(volatile unsigned long *)(0xfeff0100 + 8*(R)); }) +#define __get_DAMK(R) ({ *(volatile unsigned long *)(0xfeff0110 + 8*(R)); }) + + +#endif /* _ASM_BUSCTL_REGS_H */ diff --git a/arch/frv/include/asm/byteorder.h b/arch/frv/include/asm/byteorder.h new file mode 100644 index 0000000..f29b759 --- /dev/null +++ b/arch/frv/include/asm/byteorder.h @@ -0,0 +1,6 @@ +#ifndef _ASM_BYTEORDER_H +#define _ASM_BYTEORDER_H + +#include <linux/byteorder/big_endian.h> + +#endif /* _ASM_BYTEORDER_H */ diff --git a/arch/frv/include/asm/cache.h b/arch/frv/include/asm/cache.h new file mode 100644 index 0000000..2797163 --- /dev/null +++ b/arch/frv/include/asm/cache.h @@ -0,0 +1,23 @@ +/* cache.h: FRV cache definitions + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef __ASM_CACHE_H +#define __ASM_CACHE_H + + +/* bytes per L1 cache line */ +#define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT) +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +#define __cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) +#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) + +#endif diff --git a/arch/frv/include/asm/cacheflush.h b/arch/frv/include/asm/cacheflush.h new file mode 100644 index 0000000..432a69e --- /dev/null +++ b/arch/frv/include/asm/cacheflush.h @@ -0,0 +1,104 @@ +/* cacheflush.h: FRV cache flushing routines + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_CACHEFLUSH_H +#define _ASM_CACHEFLUSH_H + +/* Keep includes the same across arches. */ +#include <linux/mm.h> + +/* + * virtually-indexed cache management (our cache is physically indexed) + */ +#define flush_cache_all() do {} while(0) +#define flush_cache_mm(mm) do {} while(0) +#define flush_cache_dup_mm(mm) do {} while(0) +#define flush_cache_range(mm, start, end) do {} while(0) +#define flush_cache_page(vma, vmaddr, pfn) do {} while(0) +#define flush_cache_vmap(start, end) do {} while(0) +#define flush_cache_vunmap(start, end) do {} while(0) +#define flush_dcache_mmap_lock(mapping) do {} while(0) +#define flush_dcache_mmap_unlock(mapping) do {} while(0) + +/* + * physically-indexed cache management + * - see arch/frv/lib/cache.S + */ +extern void frv_dcache_writeback(unsigned long start, unsigned long size); +extern void frv_cache_invalidate(unsigned long start, unsigned long size); +extern void frv_icache_invalidate(unsigned long start, unsigned long size); +extern void frv_cache_wback_inv(unsigned long start, unsigned long size); + +static inline void __flush_cache_all(void) +{ + asm volatile(" dcef @(gr0,gr0),#1 \n" + " icei @(gr0,gr0),#1 \n" + " membar \n" + : : : "memory" + ); +} + +/* dcache/icache coherency... */ +#ifdef CONFIG_MMU +extern void flush_dcache_page(struct page *page); +#else +static inline void flush_dcache_page(struct page *page) +{ + unsigned long addr = page_to_phys(page); + frv_dcache_writeback(addr, addr + PAGE_SIZE); +} +#endif + +static inline void flush_page_to_ram(struct page *page) +{ + flush_dcache_page(page); +} + +static inline void flush_icache(void) +{ + __flush_cache_all(); +} + +static inline void flush_icache_range(unsigned long start, unsigned long end) +{ + frv_cache_wback_inv(start, end); +} + +#ifdef CONFIG_MMU +extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long start, unsigned long len); +#else +static inline void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long start, unsigned long len) +{ + frv_cache_wback_inv(start, start + len); +} +#endif + +static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + flush_icache_user_range(vma, page, page_to_phys(page), PAGE_SIZE); +} + +/* + * permit ptrace to access another process's address space through the icache + * and the dcache + */ +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ +do { \ + memcpy((dst), (src), (len)); \ + flush_icache_user_range((vma), (page), (vaddr), (len)); \ +} while(0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy((dst), (src), (len)) + +#endif /* _ASM_CACHEFLUSH_H */ diff --git a/arch/frv/include/asm/checksum.h b/arch/frv/include/asm/checksum.h new file mode 100644 index 0000000..269da09 --- /dev/null +++ b/arch/frv/include/asm/checksum.h @@ -0,0 +1,180 @@ +/* checksum.h: FRV checksumming + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_CHECKSUM_H +#define _ASM_CHECKSUM_H + +#include <linux/in6.h> + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); + +/* + * the same as csum_partial_copy, but copies from user space. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *csum_err); + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + */ +static inline +__sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int tmp, inc, sum = 0; + + asm(" addcc gr0,gr0,gr0,icc0\n" /* clear icc0.C */ + " subi %1,#4,%1 \n" + "0: \n" + " ldu.p @(%1,%3),%4 \n" + " subicc %2,#1,%2,icc1 \n" + " addxcc.p %4,%0,%0,icc0 \n" + " bhi icc1,#2,0b \n" + + /* fold the 33-bit result into 16-bits */ + " addxcc gr0,%0,%0,icc0 \n" + " srli %0,#16,%1 \n" + " sethi #0,%0 \n" + " add %1,%0,%0 \n" + " srli %0,#16,%1 \n" + " add %1,%0,%0 \n" + + : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (inc), "=&r"(tmp) + : "0" (sum), "1" (iph), "2" (ihl), "3" (4), + "m"(*(volatile struct { int _[100]; } *)iph) + : "icc0", "icc1", "memory" + ); + + return (__force __sum16)~sum; +} + +/* + * Fold a partial checksum + */ +static inline __sum16 csum_fold(__wsum sum) +{ + unsigned int tmp; + + asm(" srli %0,#16,%1 \n" + " sethi #0,%0 \n" + " add %1,%0,%0 \n" + " srli %0,#16,%1 \n" + " add %1,%0,%0 \n" + : "=r"(sum), "=&r"(tmp) + : "0"(sum) + ); + + return (__force __sum16)~sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + asm(" addcc %1,%0,%0,icc0 \n" + " addxcc %2,%0,%0,icc0 \n" + " addxcc %3,%0,%0,icc0 \n" + " addxcc gr0,%0,%0,icc0 \n" + : "=r" (sum) + : "r" (daddr), "r" (saddr), "r" (len + proto), "0"(sum) + : "icc0" + ); + return sum; +} + +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +extern __sum16 ip_compute_csum(const void *buff, int len); + +#define _HAVE_ARCH_IPV6_CSUM +static inline __sum16 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, + __u32 len, unsigned short proto, __wsum sum) +{ + unsigned long tmp, tmp2; + + asm(" addcc %2,%0,%0,icc0 \n" + + /* add up the source addr */ + " ldi @(%3,0),%1 \n" + " addxcc %1,%0,%0,icc0 \n" + " ldi @(%3,4),%2 \n" + " addxcc %2,%0,%0,icc0 \n" + " ldi @(%3,8),%1 \n" + " addxcc %1,%0,%0,icc0 \n" + " ldi @(%3,12),%2 \n" + " addxcc %2,%0,%0,icc0 \n" + + /* add up the dest addr */ + " ldi @(%4,0),%1 \n" + " addxcc %1,%0,%0,icc0 \n" + " ldi @(%4,4),%2 \n" + " addxcc %2,%0,%0,icc0 \n" + " ldi @(%4,8),%1 \n" + " addxcc %1,%0,%0,icc0 \n" + " ldi @(%4,12),%2 \n" + " addxcc %2,%0,%0,icc0 \n" + + /* fold the 33-bit result into 16-bits */ + " addxcc gr0,%0,%0,icc0 \n" + " srli %0,#16,%1 \n" + " sethi #0,%0 \n" + " add %1,%0,%0 \n" + " srli %0,#16,%1 \n" + " add %1,%0,%0 \n" + + : "=r" (sum), "=&r" (tmp), "=r" (tmp2) + : "r" (saddr), "r" (daddr), "0" (sum), "2" (len + proto) + : "icc0" + ); + + return (__force __sum16)~sum; +} + +#endif /* _ASM_CHECKSUM_H */ diff --git a/arch/frv/include/asm/cpu-irqs.h b/arch/frv/include/asm/cpu-irqs.h new file mode 100644 index 0000000..478f349 --- /dev/null +++ b/arch/frv/include/asm/cpu-irqs.h @@ -0,0 +1,81 @@ +/* cpu-irqs.h: on-CPU peripheral irqs + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_CPU_IRQS_H +#define _ASM_CPU_IRQS_H + +#ifndef __ASSEMBLY__ + +/* IRQ to level mappings */ +#define IRQ_GDBSTUB_LEVEL 15 +#define IRQ_UART_LEVEL 13 + +#ifdef CONFIG_GDBSTUB_UART0 +#define IRQ_UART0_LEVEL IRQ_GDBSTUB_LEVEL +#else +#define IRQ_UART0_LEVEL IRQ_UART_LEVEL +#endif + +#ifdef CONFIG_GDBSTUB_UART1 +#define IRQ_UART1_LEVEL IRQ_GDBSTUB_LEVEL +#else +#define IRQ_UART1_LEVEL IRQ_UART_LEVEL +#endif + +#define IRQ_DMA0_LEVEL 14 +#define IRQ_DMA1_LEVEL 14 +#define IRQ_DMA2_LEVEL 14 +#define IRQ_DMA3_LEVEL 14 +#define IRQ_DMA4_LEVEL 14 +#define IRQ_DMA5_LEVEL 14 +#define IRQ_DMA6_LEVEL 14 +#define IRQ_DMA7_LEVEL 14 + +#define IRQ_TIMER0_LEVEL 12 +#define IRQ_TIMER1_LEVEL 11 +#define IRQ_TIMER2_LEVEL 10 + +#define IRQ_XIRQ0_LEVEL 1 +#define IRQ_XIRQ1_LEVEL 2 +#define IRQ_XIRQ2_LEVEL 3 +#define IRQ_XIRQ3_LEVEL 4 +#define IRQ_XIRQ4_LEVEL 5 +#define IRQ_XIRQ5_LEVEL 6 +#define IRQ_XIRQ6_LEVEL 7 +#define IRQ_XIRQ7_LEVEL 8 + +/* IRQ IDs presented to drivers */ +#define IRQ_CPU__UNUSED IRQ_BASE_CPU +#define IRQ_CPU_UART0 (IRQ_BASE_CPU + IRQ_UART0_LEVEL) +#define IRQ_CPU_UART1 (IRQ_BASE_CPU + IRQ_UART1_LEVEL) +#define IRQ_CPU_TIMER0 (IRQ_BASE_CPU + IRQ_TIMER0_LEVEL) +#define IRQ_CPU_TIMER1 (IRQ_BASE_CPU + IRQ_TIMER1_LEVEL) +#define IRQ_CPU_TIMER2 (IRQ_BASE_CPU + IRQ_TIMER2_LEVEL) +#define IRQ_CPU_DMA0 (IRQ_BASE_CPU + IRQ_DMA0_LEVEL) +#define IRQ_CPU_DMA1 (IRQ_BASE_CPU + IRQ_DMA1_LEVEL) +#define IRQ_CPU_DMA2 (IRQ_BASE_CPU + IRQ_DMA2_LEVEL) +#define IRQ_CPU_DMA3 (IRQ_BASE_CPU + IRQ_DMA3_LEVEL) +#define IRQ_CPU_DMA4 (IRQ_BASE_CPU + IRQ_DMA4_LEVEL) +#define IRQ_CPU_DMA5 (IRQ_BASE_CPU + IRQ_DMA5_LEVEL) +#define IRQ_CPU_DMA6 (IRQ_BASE_CPU + IRQ_DMA6_LEVEL) +#define IRQ_CPU_DMA7 (IRQ_BASE_CPU + IRQ_DMA7_LEVEL) +#define IRQ_CPU_EXTERNAL0 (IRQ_BASE_CPU + IRQ_XIRQ0_LEVEL) +#define IRQ_CPU_EXTERNAL1 (IRQ_BASE_CPU + IRQ_XIRQ1_LEVEL) +#define IRQ_CPU_EXTERNAL2 (IRQ_BASE_CPU + IRQ_XIRQ2_LEVEL) +#define IRQ_CPU_EXTERNAL3 (IRQ_BASE_CPU + IRQ_XIRQ3_LEVEL) +#define IRQ_CPU_EXTERNAL4 (IRQ_BASE_CPU + IRQ_XIRQ4_LEVEL) +#define IRQ_CPU_EXTERNAL5 (IRQ_BASE_CPU + IRQ_XIRQ5_LEVEL) +#define IRQ_CPU_EXTERNAL6 (IRQ_BASE_CPU + IRQ_XIRQ6_LEVEL) +#define IRQ_CPU_EXTERNAL7 (IRQ_BASE_CPU + IRQ_XIRQ7_LEVEL) + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_CPU_IRQS_H */ diff --git a/arch/frv/include/asm/cpumask.h b/arch/frv/include/asm/cpumask.h new file mode 100644 index 0000000..d999c20 --- /dev/null +++ b/arch/frv/include/asm/cpumask.h @@ -0,0 +1,6 @@ +#ifndef _ASM_CPUMASK_H +#define _ASM_CPUMASK_H + +#include <asm-generic/cpumask.h> + +#endif /* _ASM_CPUMASK_H */ diff --git a/arch/frv/include/asm/cputime.h b/arch/frv/include/asm/cputime.h new file mode 100644 index 0000000..f6c373a --- /dev/null +++ b/arch/frv/include/asm/cputime.h @@ -0,0 +1,6 @@ +#ifndef _ASM_CPUTIME_H +#define _ASM_CPUTIME_H + +#include <asm-generic/cputime.h> + +#endif /* _ASM_CPUTIME_H */ diff --git a/arch/frv/include/asm/current.h b/arch/frv/include/asm/current.h new file mode 100644 index 0000000..86b0274 --- /dev/null +++ b/arch/frv/include/asm/current.h @@ -0,0 +1,30 @@ +/* current.h: FRV current task pointer + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_CURRENT_H +#define _ASM_CURRENT_H + +#ifndef __ASSEMBLY__ + +/* + * dedicate GR29 to keeping the current task pointer + */ +register struct task_struct *current asm("gr29"); + +#define get_current() current + +#else + +#define CURRENT gr29 + +#endif + +#endif /* _ASM_CURRENT_H */ diff --git a/arch/frv/include/asm/delay.h b/arch/frv/include/asm/delay.h new file mode 100644 index 0000000..597b4eb --- /dev/null +++ b/arch/frv/include/asm/delay.h @@ -0,0 +1,50 @@ +/* delay.h: FRV delay code + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_DELAY_H +#define _ASM_DELAY_H + +#include <asm/param.h> +#include <asm/timer-regs.h> + +/* + * delay loop - runs at __core_clock_speed_HZ / 2 [there are 2 insns in the loop] + */ +extern unsigned long __delay_loops_MHz; + +static inline void __delay(unsigned long loops) +{ + asm volatile("1: subicc %0,#1,%0,icc0 \n" + " bnc icc0,#2,1b \n" + : "=r" (loops) + : "0" (loops) + : "icc0" + ); +} + +/* + * Use only for very small delays ( < 1 msec). Should probably use a + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) + */ + +extern unsigned long loops_per_jiffy; + +static inline void udelay(unsigned long usecs) +{ + __delay(usecs * __delay_loops_MHz); +} + +#define ndelay(n) udelay((n) * 5) + +#endif /* _ASM_DELAY_H */ diff --git a/arch/frv/include/asm/device.h b/arch/frv/include/asm/device.h new file mode 100644 index 0000000..d8f9872 --- /dev/null +++ b/arch/frv/include/asm/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include <asm-generic/device.h> + diff --git a/arch/frv/include/asm/div64.h b/arch/frv/include/asm/div64.h new file mode 100644 index 0000000..6cd978c --- /dev/null +++ b/arch/frv/include/asm/div64.h @@ -0,0 +1 @@ +#include <asm-generic/div64.h> diff --git a/arch/frv/include/asm/dm9000.h b/arch/frv/include/asm/dm9000.h new file mode 100644 index 0000000..f6f48fd --- /dev/null +++ b/arch/frv/include/asm/dm9000.h @@ -0,0 +1,37 @@ +/* dm9000.h: Davicom DM9000 adapter configuration + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_DM9000_H +#define _ASM_DM9000_H + +#include <asm/mb-regs.h> + +#define DM9000_ARCH_IOBASE (__region_CS6 + 0x300) +#define DM9000_ARCH_IRQ IRQ_CPU_EXTERNAL3 /* XIRQ #3 (shared with FPGA) */ +#undef DM9000_ARCH_IRQ_ACTLOW /* IRQ pin active high */ +#define DM9000_ARCH_BUS_INFO "CS6#+0x300" /* bus info for ethtool */ + +#undef __is_PCI_IO +#define __is_PCI_IO(addr) 0 /* not PCI */ + +#undef inl +#define inl(addr) \ +({ \ + unsigned long __ioaddr = (unsigned long) addr; \ + uint32_t x = readl(__ioaddr); \ + ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff); \ +}) + +#undef insl +#define insl(a,b,l) __insl(a,b,l,0) /* don't byte-swap */ + + +#endif /* _ASM_DM9000_H */ diff --git a/arch/frv/include/asm/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h new file mode 100644 index 0000000..b289887 --- /dev/null +++ b/arch/frv/include/asm/dma-mapping.h @@ -0,0 +1,174 @@ +#ifndef _ASM_DMA_MAPPING_H +#define _ASM_DMA_MAPPING_H + +#include <linux/device.h> +#include <asm/cache.h> +#include <asm/cacheflush.h> +#include <asm/scatterlist.h> +#include <asm/io.h> + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) + +extern unsigned long __nongprelbss dma_coherent_mem_start; +extern unsigned long __nongprelbss dma_coherent_mem_end; + +void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp); +void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); + +/* + * Map a single buffer of the indicated size for DMA in streaming mode. + * The 32-bit bus address to use is returned. + * + * Once the device is given the dma address, the device owns this memory + * until either pci_unmap_single or pci_dma_sync_single is performed. + */ +extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction); + +/* + * Unmap a single streaming mode DMA translation. The dma_addr and size + * must match what was provided for in a previous pci_map_single call. All + * other usages are undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see + * whatever the device wrote there. + */ +static inline +void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +/* + * Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scather-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction); + +/* + * Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +static inline +void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +extern +dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, + size_t size, enum dma_data_direction direction); + +static inline +void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + + +static inline +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ +} + +static inline +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ + flush_write_buffers(); +} + +static inline +void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ +} + +static inline +void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + flush_write_buffers(); +} + +static inline +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ +} + +static inline +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + flush_write_buffers(); +} + +static inline +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} + +static inline +int dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, + * so we can't guarantee allocations that must be + * within a tighter range than GFP_DMA.. + */ + if (mask < 0x00ffffff) + return 0; + + return 1; +} + +static inline +int dma_set_mask(struct device *dev, u64 mask) +{ + if (!dev->dma_mask || !dma_supported(dev, mask)) + return -EIO; + + *dev->dma_mask = mask; + + return 0; +} + +static inline +int dma_get_cache_alignment(void) +{ + return 1 << L1_CACHE_SHIFT; +} + +#define dma_is_consistent(d, h) (1) + +static inline +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction direction) +{ + flush_write_buffers(); +} + +#endif /* _ASM_DMA_MAPPING_H */ diff --git a/arch/frv/include/asm/dma.h b/arch/frv/include/asm/dma.h new file mode 100644 index 0000000..683c47d --- /dev/null +++ b/arch/frv/include/asm/dma.h @@ -0,0 +1,125 @@ +/* dma.h: FRV DMA controller management + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_DMA_H +#define _ASM_DMA_H + +//#define DMA_DEBUG 1 + +#include <linux/interrupt.h> + +#undef MAX_DMA_CHANNELS /* don't use kernel/dma.c */ + +/* under 2.4 this is actually needed by the new bootmem allocator */ +#define MAX_DMA_ADDRESS PAGE_OFFSET + +/* + * FRV DMA controller management + */ +typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data); + +extern void frv_dma_init(void); + +extern int frv_dma_open(const char *devname, + unsigned long dmamask, + int dmacap, + dma_irq_handler_t handler, + unsigned long irq_flags, + void *data); + +/* channels required */ +#define FRV_DMA_MASK_ANY ULONG_MAX /* any channel */ + +/* capabilities required */ +#define FRV_DMA_CAP_DREQ 0x01 /* DMA request pin */ +#define FRV_DMA_CAP_DACK 0x02 /* DMA ACK pin */ +#define FRV_DMA_CAP_DONE 0x04 /* DMA done pin */ + +extern void frv_dma_close(int dma); + +extern void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr); + +extern void frv_dma_start(int dma, + unsigned long sba, unsigned long dba, + unsigned long pix, unsigned long six, unsigned long bcl); + +extern void frv_dma_restart_circular(int dma, unsigned long six); + +extern void frv_dma_stop(int dma); + +extern int is_frv_dma_interrupting(int dma); + +extern void frv_dma_dump(int dma); + +extern void frv_dma_status_clear(int dma); + +#define FRV_DMA_NCHANS 8 +#define FRV_DMA_4CHANS 4 +#define FRV_DMA_8CHANS 8 + +#define DMAC_CCFRx 0x00 /* channel configuration reg */ +#define DMAC_CCFRx_CM_SHIFT 16 +#define DMAC_CCFRx_CM_DA 0x00000000 +#define DMAC_CCFRx_CM_SCA 0x00010000 +#define DMAC_CCFRx_CM_DCA 0x00020000 +#define DMAC_CCFRx_CM_2D 0x00030000 +#define DMAC_CCFRx_ATS_SHIFT 8 +#define DMAC_CCFRx_RS_INTERN 0x00000000 +#define DMAC_CCFRx_RS_EXTERN 0x00000001 +#define DMAC_CCFRx_RS_SHIFT 0 + +#define DMAC_CSTRx 0x08 /* channel status reg */ +#define DMAC_CSTRx_FS 0x0000003f +#define DMAC_CSTRx_NE 0x00000100 +#define DMAC_CSTRx_FED 0x00000200 +#define DMAC_CSTRx_WER 0x00000800 +#define DMAC_CSTRx_RER 0x00001000 +#define DMAC_CSTRx_CE 0x00002000 +#define DMAC_CSTRx_INT 0x00800000 +#define DMAC_CSTRx_BUSY 0x80000000 + +#define DMAC_CCTRx 0x10 /* channel control reg */ +#define DMAC_CCTRx_DSIZ_1 0x00000000 +#define DMAC_CCTRx_DSIZ_2 0x00000001 +#define DMAC_CCTRx_DSIZ_4 0x00000002 +#define DMAC_CCTRx_DSIZ_32 0x00000005 +#define DMAC_CCTRx_DAU_HOLD 0x00000000 +#define DMAC_CCTRx_DAU_INC 0x00000010 +#define DMAC_CCTRx_DAU_DEC 0x00000020 +#define DMAC_CCTRx_SSIZ_1 0x00000000 +#define DMAC_CCTRx_SSIZ_2 0x00000100 +#define DMAC_CCTRx_SSIZ_4 0x00000200 +#define DMAC_CCTRx_SSIZ_32 0x00000500 +#define DMAC_CCTRx_SAU_HOLD 0x00000000 +#define DMAC_CCTRx_SAU_INC 0x00001000 +#define DMAC_CCTRx_SAU_DEC 0x00002000 +#define DMAC_CCTRx_FC 0x08000000 +#define DMAC_CCTRx_ICE 0x10000000 +#define DMAC_CCTRx_IE 0x40000000 +#define DMAC_CCTRx_ACT 0x80000000 + +#define DMAC_SBAx 0x18 /* source base address reg */ +#define DMAC_DBAx 0x20 /* data base address reg */ +#define DMAC_PIXx 0x28 /* primary index reg */ +#define DMAC_SIXx 0x30 /* secondary index reg */ +#define DMAC_BCLx 0x38 /* byte count limit reg */ +#define DMAC_APRx 0x40 /* alternate pointer reg */ + +/* + * required for PCI + MODULES + */ +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif + +#endif /* _ASM_DMA_H */ diff --git a/arch/frv/include/asm/elf.h b/arch/frv/include/asm/elf.h new file mode 100644 index 0000000..7279ec0 --- /dev/null +++ b/arch/frv/include/asm/elf.h @@ -0,0 +1,142 @@ +/* elf.h: FR-V ELF definitions + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from include/asm-m68knommu/elf.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef __ASM_ELF_H +#define __ASM_ELF_H + +#include <asm/ptrace.h> +#include <asm/user.h> + +struct elf32_hdr; + +/* + * ELF header e_flags defines. + */ +#define EF_FRV_GPR_MASK 0x00000003 /* mask for # of gprs */ +#define EF_FRV_GPR32 0x00000001 /* Only uses GR on 32-register */ +#define EF_FRV_GPR64 0x00000002 /* Only uses GR on 64-register */ +#define EF_FRV_FPR_MASK 0x0000000c /* mask for # of fprs */ +#define EF_FRV_FPR32 0x00000004 /* Only uses FR on 32-register */ +#define EF_FRV_FPR64 0x00000008 /* Only uses FR on 64-register */ +#define EF_FRV_FPR_NONE 0x0000000C /* Uses software floating-point */ +#define EF_FRV_DWORD_MASK 0x00000030 /* mask for dword support */ +#define EF_FRV_DWORD_YES 0x00000010 /* Assumes stack aligned to 8-byte boundaries. */ +#define EF_FRV_DWORD_NO 0x00000020 /* Assumes stack aligned to 4-byte boundaries. */ +#define EF_FRV_DOUBLE 0x00000040 /* Uses double instructions. */ +#define EF_FRV_MEDIA 0x00000080 /* Uses media instructions. */ +#define EF_FRV_PIC 0x00000100 /* Uses position independent code. */ +#define EF_FRV_NON_PIC_RELOCS 0x00000200 /* Does not use position Independent code. */ +#define EF_FRV_MULADD 0x00000400 /* -mmuladd */ +#define EF_FRV_BIGPIC 0x00000800 /* -fPIC */ +#define EF_FRV_LIBPIC 0x00001000 /* -mlibrary-pic */ +#define EF_FRV_G0 0x00002000 /* -G 0, no small data ptr */ +#define EF_FRV_NOPACK 0x00004000 /* -mnopack */ +#define EF_FRV_FDPIC 0x00008000 /* -mfdpic */ +#define EF_FRV_CPU_MASK 0xff000000 /* specific cpu bits */ +#define EF_FRV_CPU_GENERIC 0x00000000 /* Set CPU type is FR-V */ +#define EF_FRV_CPU_FR500 0x01000000 /* Set CPU type is FR500 */ +#define EF_FRV_CPU_FR300 0x02000000 /* Set CPU type is FR300 */ +#define EF_FRV_CPU_SIMPLE 0x03000000 /* SIMPLE */ +#define EF_FRV_CPU_TOMCAT 0x04000000 /* Tomcat, FR500 prototype */ +#define EF_FRV_CPU_FR400 0x05000000 /* Set CPU type is FR400 */ +#define EF_FRV_CPU_FR550 0x06000000 /* Set CPU type is FR550 */ +#define EF_FRV_CPU_FR405 0x07000000 /* Set CPU type is FR405 */ +#define EF_FRV_CPU_FR450 0x08000000 /* Set CPU type is FR450 */ + +/* + * FR-V ELF relocation types + */ + + +/* + * ELF register definitions.. + */ +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_fpmedia_regs elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +extern int elf_check_arch(const struct elf32_hdr *hdr); + +#define elf_check_fdpic(x) ((x)->e_flags & EF_FRV_FDPIC && !((x)->e_flags & EF_FRV_NON_PIC_RELOCS)) +#define elf_check_const_displacement(x) ((x)->e_flags & EF_FRV_PIC) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB +#define ELF_ARCH EM_FRV + +#define ELF_PLAT_INIT(_r) \ +do { \ + __kernel_frame0_ptr->gr16 = 0; \ + __kernel_frame0_ptr->gr17 = 0; \ + __kernel_frame0_ptr->gr18 = 0; \ + __kernel_frame0_ptr->gr19 = 0; \ + __kernel_frame0_ptr->gr20 = 0; \ + __kernel_frame0_ptr->gr21 = 0; \ + __kernel_frame0_ptr->gr22 = 0; \ + __kernel_frame0_ptr->gr23 = 0; \ + __kernel_frame0_ptr->gr24 = 0; \ + __kernel_frame0_ptr->gr25 = 0; \ + __kernel_frame0_ptr->gr26 = 0; \ + __kernel_frame0_ptr->gr27 = 0; \ + __kernel_frame0_ptr->gr29 = 0; \ +} while(0) + +#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, _dynamic_addr) \ +do { \ + __kernel_frame0_ptr->gr16 = _exec_map_addr; \ + __kernel_frame0_ptr->gr17 = _interp_map_addr; \ + __kernel_frame0_ptr->gr18 = _dynamic_addr; \ + __kernel_frame0_ptr->gr19 = 0; \ + __kernel_frame0_ptr->gr20 = 0; \ + __kernel_frame0_ptr->gr21 = 0; \ + __kernel_frame0_ptr->gr22 = 0; \ + __kernel_frame0_ptr->gr23 = 0; \ + __kernel_frame0_ptr->gr24 = 0; \ + __kernel_frame0_ptr->gr25 = 0; \ + __kernel_frame0_ptr->gr26 = 0; \ + __kernel_frame0_ptr->gr27 = 0; \ + __kernel_frame0_ptr->gr29 = 0; \ +} while(0) + +#define USE_ELF_CORE_DUMP +#define ELF_FDPIC_CORE_EFLAGS EF_FRV_FDPIC +#define ELF_EXEC_PAGESIZE 16384 + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE 0x08000000UL + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +#define ELF_HWCAP (0) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + +#define SET_PERSONALITY(ex) set_personality(PER_LINUX) + +#endif diff --git a/arch/frv/include/asm/emergency-restart.h b/arch/frv/include/asm/emergency-restart.h new file mode 100644 index 0000000..108d8c4 --- /dev/null +++ b/arch/frv/include/asm/emergency-restart.h @@ -0,0 +1,6 @@ +#ifndef _ASM_EMERGENCY_RESTART_H +#define _ASM_EMERGENCY_RESTART_H + +#include <asm-generic/emergency-restart.h> + +#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/frv/include/asm/errno.h b/arch/frv/include/asm/errno.h new file mode 100644 index 0000000..d010795 --- /dev/null +++ b/arch/frv/include/asm/errno.h @@ -0,0 +1,7 @@ +#ifndef _ASM_ERRNO_H +#define _ASM_ERRNO_H + +#include <asm-generic/errno.h> + +#endif /* _ASM_ERRNO_H */ + diff --git a/arch/frv/include/asm/fb.h b/arch/frv/include/asm/fb.h new file mode 100644 index 0000000..c7df380 --- /dev/null +++ b/arch/frv/include/asm/fb.h @@ -0,0 +1,12 @@ +#ifndef _ASM_FB_H_ +#define _ASM_FB_H_ +#include <linux/fb.h> + +#define fb_pgprotect(...) do {} while (0) + +static inline int fb_is_primary_device(struct fb_info *info) +{ + return 0; +} + +#endif /* _ASM_FB_H_ */ diff --git a/arch/frv/include/asm/fcntl.h b/arch/frv/include/asm/fcntl.h new file mode 100644 index 0000000..46ab12d --- /dev/null +++ b/arch/frv/include/asm/fcntl.h @@ -0,0 +1 @@ +#include <asm-generic/fcntl.h> diff --git a/arch/frv/include/asm/fpu.h b/arch/frv/include/asm/fpu.h new file mode 100644 index 0000000..d73c60b --- /dev/null +++ b/arch/frv/include/asm/fpu.h @@ -0,0 +1,11 @@ +#ifndef __ASM_FPU_H +#define __ASM_FPU_H + + +/* + * MAX floating point unit state size (FSAVE/FRESTORE) + */ + +#define kernel_fpu_end() do { asm volatile("bar":::"memory"); preempt_enable(); } while(0) + +#endif /* __ASM_FPU_H */ diff --git a/arch/frv/include/asm/ftrace.h b/arch/frv/include/asm/ftrace.h new file mode 100644 index 0000000..40a8c17 --- /dev/null +++ b/arch/frv/include/asm/ftrace.h @@ -0,0 +1 @@ +/* empty */ diff --git a/arch/frv/include/asm/futex.h b/arch/frv/include/asm/futex.h new file mode 100644 index 0000000..08b3d1d --- /dev/null +++ b/arch/frv/include/asm/futex.h @@ -0,0 +1,19 @@ +#ifndef _ASM_FUTEX_H +#define _ASM_FUTEX_H + +#ifdef __KERNEL__ + +#include <linux/futex.h> +#include <asm/errno.h> +#include <asm/uaccess.h> + +extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr); + +static inline int +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) +{ + return -ENOSYS; +} + +#endif +#endif diff --git a/arch/frv/include/asm/gdb-stub.h b/arch/frv/include/asm/gdb-stub.h new file mode 100644 index 0000000..24f9738 --- /dev/null +++ b/arch/frv/include/asm/gdb-stub.h @@ -0,0 +1,140 @@ +/* gdb-stub.h: FRV GDB stub + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef __ASM_GDB_STUB_H +#define __ASM_GDB_STUB_H + +#undef GDBSTUB_DEBUG_PROTOCOL + +#include <asm/ptrace.h> + +/* + * important register numbers in GDB protocol + * - GR0, GR1, GR2, GR3, GR4, GR5, GR6, GR7, + * - GR8, GR9, GR10, GR11, GR12, GR13, GR14, GR15, + * - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23, + * - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31, + * - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39, + * - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47, + * - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55, + * - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63, + * - FR0, FR1, FR2, FR3, FR4, FR5, FR6, FR7, + * - FR8, FR9, FR10, FR11, FR12, FR13, FR14, FR15, + * - FR16, FR17, FR18, FR19, FR20, FR21, FR22, FR23, + * - FR24, FR25, FR26, FR27, FR28, FR29, FR30, FR31, + * - FR32, FR33, FR34, FR35, FR36, FR37, FR38, FR39, + * - FR40, FR41, FR42, FR43, FR44, FR45, FR46, FR47, + * - FR48, FR49, FR50, FR51, FR52, FR53, FR54, FR55, + * - FR56, FR57, FR58, FR59, FR60, FR61, FR62, FR63, + * - PC, PSR, CCR, CCCR, + * - _X132, _X133, _X134 + * - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3, + * - SCR0, SCR1, SCR2, SCR3, + * - LR, LCR, + * - IACC0H, IACC0L, + * - FSR0, + * - ACC0, ACC1, ACC2, ACC3, ACC4, ACC5, ACC6, ACC7, + * - ACCG0123, ACCG4567, + * - MSR0, MSR1, + * - GNER0, GNER1, + * - FNER0, FNER1, + */ +#define GDB_REG_GR(N) (N) +#define GDB_REG_FR(N) (64+(N)) +#define GDB_REG_PC 128 +#define GDB_REG_PSR 129 +#define GDB_REG_CCR 130 +#define GDB_REG_CCCR 131 +#define GDB_REG_TBR 135 +#define GDB_REG_BRR 136 +#define GDB_REG_DBAR(N) (137+(N)) +#define GDB_REG_SCR(N) (141+(N)) +#define GDB_REG_LR 145 +#define GDB_REG_LCR 146 +#define GDB_REG_FSR0 149 +#define GDB_REG_ACC(N) (150+(N)) +#define GDB_REG_ACCG(N) (158+(N)/4) +#define GDB_REG_MSR(N) (160+(N)) +#define GDB_REG_GNER(N) (162+(N)) +#define GDB_REG_FNER(N) (164+(N)) + +#define GDB_REG_SP GDB_REG_GR(1) +#define GDB_REG_FP GDB_REG_GR(2) + +#ifndef _LANGUAGE_ASSEMBLY + +/* + * Prototypes + */ +extern void show_registers_only(struct pt_regs *regs); + +extern void gdbstub_init(void); +extern void gdbstub(int type); +extern void gdbstub_exit(int status); + +extern void gdbstub_io_init(void); +extern void gdbstub_set_baud(unsigned baud); +extern int gdbstub_rx_char(unsigned char *_ch, int nonblock); +extern void gdbstub_tx_char(unsigned char ch); +extern void gdbstub_tx_flush(void); +extern void gdbstub_do_rx(void); + +extern asmlinkage void __debug_stub_init_break(void); +extern asmlinkage void __break_hijack_kernel_event(void); +extern asmlinkage void __break_hijack_kernel_event_breaks_here(void); +extern asmlinkage void start_kernel(void); + +extern asmlinkage void gdbstub_rx_handler(void); +extern asmlinkage void gdbstub_rx_irq(void); +extern asmlinkage void gdbstub_intercept(void); + +extern uint32_t __entry_usertrap_table[]; +extern uint32_t __entry_kerneltrap_table[]; + +extern volatile u8 gdbstub_rx_buffer[PAGE_SIZE]; +extern volatile u32 gdbstub_rx_inp; +extern volatile u32 gdbstub_rx_outp; +extern volatile u8 gdbstub_rx_overflow; +extern u8 gdbstub_rx_unget; + +extern void gdbstub_printk(const char *fmt, ...); +extern void debug_to_serial(const char *p, int n); +extern void console_set_baud(unsigned baud); + +#ifdef GDBSTUB_DEBUG_PROTOCOL +#define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__) +#else +#define gdbstub_proto(FMT,...) ({ 0; }) +#endif + +/* + * we dedicate GR31 to keeping a pointer to the gdbstub exception frame + * - gr31 is destroyed on entry to the gdbstub if !MMU + * - gr31 is saved in scr3 on entry to the gdbstub if in !MMU + */ +register struct frv_frame0 *__debug_frame0 asm("gr31"); + +#define __debug_frame (&__debug_frame0->regs) +#define __debug_user_context (&__debug_frame0->uc) +#define __debug_regs (&__debug_frame0->debug) +#define __debug_reg(X) ((unsigned long *) ((unsigned long) &__debug_frame0 + (X))) + +struct frv_debug_status { + unsigned long bpsr; + unsigned long dcr; + unsigned long brr; + unsigned long nmar; +}; + +extern struct frv_debug_status __debug_status; + +#endif /* _LANGUAGE_ASSEMBLY */ +#endif /* __ASM_GDB_STUB_H */ diff --git a/arch/frv/include/asm/gpio-regs.h b/arch/frv/include/asm/gpio-regs.h new file mode 100644 index 0000000..9edf5d5 --- /dev/null +++ b/arch/frv/include/asm/gpio-regs.h @@ -0,0 +1,116 @@ +/* gpio-regs.h: on-chip general purpose I/O registers + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_GPIO_REGS +#define _ASM_GPIO_REGS + +#define __reg(ADDR) (*(volatile unsigned long *)(ADDR)) + +#define __get_PDR() ({ __reg(0xfeff0400); }) +#define __set_PDR(V) do { __reg(0xfeff0400) = (V); mb(); } while(0) + +#define __get_GPDR() ({ __reg(0xfeff0408); }) +#define __set_GPDR(V) do { __reg(0xfeff0408) = (V); mb(); } while(0) + +#define __get_SIR() ({ __reg(0xfeff0410); }) +#define __set_SIR(V) do { __reg(0xfeff0410) = (V); mb(); } while(0) + +#define __get_SOR() ({ __reg(0xfeff0418); }) +#define __set_SOR(V) do { __reg(0xfeff0418) = (V); mb(); } while(0) + +#define __set_PDSR(V) do { __reg(0xfeff0420) = (V); mb(); } while(0) + +#define __set_PDCR(V) do { __reg(0xfeff0428) = (V); mb(); } while(0) + +#define __get_RSTR() ({ __reg(0xfeff0500); }) +#define __set_RSTR(V) do { __reg(0xfeff0500) = (V); mb(); } while(0) + + + +/* PDR definitions */ +#define PDR_GPIO_DATA(X) (1 << (X)) + +/* GPDR definitions */ +#define GPDR_INPUT 0 +#define GPDR_OUTPUT 1 +#define GPDR_DREQ0_BIT 0x00001000 +#define GPDR_DREQ1_BIT 0x00008000 +#define GPDR_DREQ2_BIT 0x00040000 +#define GPDR_DREQ3_BIT 0x00080000 +#define GPDR_DREQ4_BIT 0x00004000 +#define GPDR_DREQ5_BIT 0x00020000 +#define GPDR_DREQ6_BIT 0x00100000 +#define GPDR_DREQ7_BIT 0x00200000 +#define GPDR_DACK0_BIT 0x00002000 +#define GPDR_DACK1_BIT 0x00010000 +#define GPDR_DACK2_BIT 0x00100000 +#define GPDR_DACK3_BIT 0x00200000 +#define GPDR_DONE0_BIT 0x00004000 +#define GPDR_DONE1_BIT 0x00020000 +#define GPDR_GPIO_DIR(X,D) ((D) << (X)) + +/* SIR definitions */ +#define SIR_GPIO_INPUT 0 +#define SIR_DREQ7_INPUT 0x00200000 +#define SIR_DREQ6_INPUT 0x00100000 +#define SIR_DREQ3_INPUT 0x00080000 +#define SIR_DREQ2_INPUT 0x00040000 +#define SIR_DREQ5_INPUT 0x00020000 +#define SIR_DREQ1_INPUT 0x00008000 +#define SIR_DREQ4_INPUT 0x00004000 +#define SIR_DREQ0_INPUT 0x00001000 +#define SIR_RXD1_INPUT 0x00000400 +#define SIR_CTS0_INPUT 0x00000100 +#define SIR_RXD0_INPUT 0x00000040 +#define SIR_GATE1_INPUT 0x00000020 +#define SIR_GATE0_INPUT 0x00000010 +#define SIR_IRQ3_INPUT 0x00000008 +#define SIR_IRQ2_INPUT 0x00000004 +#define SIR_IRQ1_INPUT 0x00000002 +#define SIR_IRQ0_INPUT 0x00000001 +#define SIR_DREQ_BITS (SIR_DREQ0_INPUT | SIR_DREQ1_INPUT | \ + SIR_DREQ2_INPUT | SIR_DREQ3_INPUT | \ + SIR_DREQ4_INPUT | SIR_DREQ5_INPUT | \ + SIR_DREQ6_INPUT | SIR_DREQ7_INPUT) + +/* SOR definitions */ +#define SOR_GPIO_OUTPUT 0 +#define SOR_DACK3_OUTPUT 0x00200000 +#define SOR_DACK2_OUTPUT 0x00100000 +#define SOR_DONE1_OUTPUT 0x00020000 +#define SOR_DACK1_OUTPUT 0x00010000 +#define SOR_DONE0_OUTPUT 0x00004000 +#define SOR_DACK0_OUTPUT 0x00002000 +#define SOR_TXD1_OUTPUT 0x00000800 +#define SOR_RTS0_OUTPUT 0x00000200 +#define SOR_TXD0_OUTPUT 0x00000080 +#define SOR_TOUT1_OUTPUT 0x00000020 +#define SOR_TOUT0_OUTPUT 0x00000010 +#define SOR_DONE_BITS (SOR_DONE0_OUTPUT | SOR_DONE1_OUTPUT) +#define SOR_DACK_BITS (SOR_DACK0_OUTPUT | SOR_DACK1_OUTPUT | \ + SOR_DACK2_OUTPUT | SOR_DACK3_OUTPUT) + +/* PDSR definitions */ +#define PDSR_UNCHANGED 0 +#define PDSR_SET_BIT(X) (1 << (X)) + +/* PDCR definitions */ +#define PDCR_UNCHANGED 0 +#define PDCR_CLEAR_BIT(X) (1 << (X)) + +/* RSTR definitions */ +/* Read Only */ +#define RSTR_POWERON 0x00000400 +#define RSTR_SOFTRESET_STATUS 0x00000100 +/* Write Only */ +#define RSTR_SOFTRESET 0x00000001 + +#endif /* _ASM_GPIO_REGS */ diff --git a/arch/frv/include/asm/hardirq.h b/arch/frv/include/asm/hardirq.h new file mode 100644 index 0000000..fc47515 --- /dev/null +++ b/arch/frv/include/asm/hardirq.h @@ -0,0 +1,35 @@ +/* hardirq.h: FRV hardware IRQ management + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef __ASM_HARDIRQ_H +#define __ASM_HARDIRQ_H + +#include <linux/threads.h> +#include <linux/irq.h> + +typedef struct { + unsigned int __softirq_pending; + unsigned long idle_timestamp; +} ____cacheline_aligned irq_cpustat_t; + +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ + +#ifdef CONFIG_SMP +#error SMP not available on FR-V +#endif /* CONFIG_SMP */ + +extern atomic_t irq_err_count; +static inline void ack_bad_irq(int irq) +{ + atomic_inc(&irq_err_count); +} + +#endif diff --git a/arch/frv/include/asm/highmem.h b/arch/frv/include/asm/highmem.h new file mode 100644 index 0000000..68e4677 --- /dev/null +++ b/arch/frv/include/asm/highmem.h @@ -0,0 +1,182 @@ +/* highmem.h: virtual kernel memory mappings for high memory + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from include/asm-i386/highmem.h + * + * See Documentation/frv/mmu-layout.txt for more information. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_HIGHMEM_H +#define _ASM_HIGHMEM_H + +#ifdef __KERNEL__ + +#include <linux/init.h> +#include <linux/highmem.h> +#include <asm/mem-layout.h> +#include <asm/spr-regs.h> +#include <asm/mb-regs.h> + +#define NR_TLB_LINES 64 /* number of lines in the TLB */ + +#ifndef __ASSEMBLY__ + +#include <linux/interrupt.h> +#include <asm/kmap_types.h> +#include <asm/pgtable.h> + +#ifdef CONFIG_DEBUG_HIGHMEM +#define HIGHMEM_DEBUG 1 +#else +#define HIGHMEM_DEBUG 0 +#endif + +/* declarations for highmem.c */ +extern unsigned long highstart_pfn, highend_pfn; + +#define kmap_prot PAGE_KERNEL +#define kmap_pte ______kmap_pte_in_TLB +extern pte_t *pkmap_page_table; + +#define flush_cache_kmaps() do { } while (0) + +/* + * Right now we initialize only a single pte table. It can be extended + * easily, subsequent pte tables have to be allocated in one physical + * chunk of RAM. + */ +#define LAST_PKMAP PTRS_PER_PTE +#define LAST_PKMAP_MASK (LAST_PKMAP - 1) +#define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT) +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) + +extern void *kmap_high(struct page *page); +extern void kunmap_high(struct page *page); + +extern void *kmap(struct page *page); +extern void kunmap(struct page *page); + +extern struct page *kmap_atomic_to_page(void *ptr); + +#endif /* !__ASSEMBLY__ */ + +/* + * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap + * gives a more generic (and caching) interface. But kmap_atomic can + * be used in IRQ contexts, so in some (very limited) cases we need + * it. + */ +#define KMAP_ATOMIC_CACHE_DAMR 8 + +#ifndef __ASSEMBLY__ + +#define __kmap_atomic_primary(type, paddr, ampr) \ +({ \ + unsigned long damlr, dampr; \ + \ + dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \ + \ + if (type != __KM_CACHE) \ + asm volatile("movgs %0,dampr"#ampr :: "r"(dampr) : "memory"); \ + else \ + asm volatile("movgs %0,iampr"#ampr"\n" \ + "movgs %0,dampr"#ampr"\n" \ + :: "r"(dampr) : "memory" \ + ); \ + \ + asm("movsg damlr"#ampr",%0" : "=r"(damlr)); \ + \ + /*printk("DAMR"#ampr": PRIM sl=%d L=%08lx P=%08lx\n", type, damlr, dampr);*/ \ + \ + (void *) damlr; \ +}) + +#define __kmap_atomic_secondary(slot, paddr) \ +({ \ + unsigned long damlr = KMAP_ATOMIC_SECONDARY_FRAME + (slot) * PAGE_SIZE; \ + unsigned long dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \ + \ + asm volatile("movgs %0,tplr \n" \ + "movgs %1,tppr \n" \ + "tlbpr %0,gr0,#2,#1" \ + : : "r"(damlr), "r"(dampr) : "memory"); \ + \ + /*printk("TLB: SECN sl=%d L=%08lx P=%08lx\n", slot, damlr, dampr);*/ \ + \ + (void *) damlr; \ +}) + +static inline void *kmap_atomic(struct page *page, enum km_type type) +{ + unsigned long paddr; + + pagefault_disable(); + debug_kmap_atomic(type); + paddr = page_to_phys(page); + + switch (type) { + case 0: return __kmap_atomic_primary(0, paddr, 2); + case 1: return __kmap_atomic_primary(1, paddr, 3); + case 2: return __kmap_atomic_primary(2, paddr, 4); + case 3: return __kmap_atomic_primary(3, paddr, 5); + case 4: return __kmap_atomic_primary(4, paddr, 6); + case 5: return __kmap_atomic_primary(5, paddr, 7); + case 6: return __kmap_atomic_primary(6, paddr, 8); + case 7: return __kmap_atomic_primary(7, paddr, 9); + case 8: return __kmap_atomic_primary(8, paddr, 10); + + case 9 ... 9 + NR_TLB_LINES - 1: + return __kmap_atomic_secondary(type - 9, paddr); + + default: + BUG(); + return NULL; + } +} + +#define __kunmap_atomic_primary(type, ampr) \ +do { \ + asm volatile("movgs gr0,dampr"#ampr"\n" ::: "memory"); \ + if (type == __KM_CACHE) \ + asm volatile("movgs gr0,iampr"#ampr"\n" ::: "memory"); \ +} while(0) + +#define __kunmap_atomic_secondary(slot, vaddr) \ +do { \ + asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \ +} while(0) + +static inline void kunmap_atomic(void *kvaddr, enum km_type type) +{ + switch (type) { + case 0: __kunmap_atomic_primary(0, 2); break; + case 1: __kunmap_atomic_primary(1, 3); break; + case 2: __kunmap_atomic_primary(2, 4); break; + case 3: __kunmap_atomic_primary(3, 5); break; + case 4: __kunmap_atomic_primary(4, 6); break; + case 5: __kunmap_atomic_primary(5, 7); break; + case 6: __kunmap_atomic_primary(6, 8); break; + case 7: __kunmap_atomic_primary(7, 9); break; + case 8: __kunmap_atomic_primary(8, 10); break; + + case 9 ... 9 + NR_TLB_LINES - 1: + __kunmap_atomic_secondary(type - 9, kvaddr); + break; + + default: + BUG(); + } + pagefault_enable(); +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_HIGHMEM_H */ diff --git a/arch/frv/include/asm/hw_irq.h b/arch/frv/include/asm/hw_irq.h new file mode 100644 index 0000000..522ad37 --- /dev/null +++ b/arch/frv/include/asm/hw_irq.h @@ -0,0 +1,16 @@ +/* hw_irq.h: FR-V specific h/w IRQ stuff + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_HW_IRQ_H +#define _ASM_HW_IRQ_H + + +#endif /* _ASM_HW_IRQ_H */ diff --git a/arch/frv/include/asm/init.h b/arch/frv/include/asm/init.h new file mode 100644 index 0000000..8b15838 --- /dev/null +++ b/arch/frv/include/asm/init.h @@ -0,0 +1,12 @@ +#ifndef _ASM_INIT_H +#define _ASM_INIT_H + +#define __init __attribute__ ((__section__ (".text.init"))) +#define __initdata __attribute__ ((__section__ (".data.init"))) +/* For assembly routines */ +#define __INIT .section ".text.init",#alloc,#execinstr +#define __FINIT .previous +#define __INITDATA .section ".data.init",#alloc,#write + +#endif + diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h new file mode 100644 index 0000000..ca7475e --- /dev/null +++ b/arch/frv/include/asm/io.h @@ -0,0 +1,392 @@ +/* io.h: FRV I/O operations + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This gets interesting when talking to the PCI bus - the CPU is in big endian + * mode, the PCI bus is little endian and the hardware in the middle can do + * byte swapping + */ +#ifndef _ASM_IO_H +#define _ASM_IO_H + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <asm/virtconvert.h> +#include <asm/string.h> +#include <asm/mb-regs.h> +#include <linux/delay.h> + +/* + * swap functions are sometimes needed to interface little-endian hardware + */ + +static inline unsigned short _swapw(unsigned short v) +{ + return ((v << 8) | (v >> 8)); +} + +static inline unsigned long _swapl(unsigned long v) +{ + return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24)); +} + +//#define __iormb() asm volatile("membar") +//#define __iowmb() asm volatile("membar") + +#define __raw_readb __builtin_read8 +#define __raw_readw __builtin_read16 +#define __raw_readl __builtin_read32 + +#define __raw_writeb(datum, addr) __builtin_write8(addr, datum) +#define __raw_writew(datum, addr) __builtin_write16(addr, datum) +#define __raw_writel(datum, addr) __builtin_write32(addr, datum) + +static inline void io_outsb(unsigned int addr, const void *buf, int len) +{ + unsigned long __ioaddr = (unsigned long) addr; + const uint8_t *bp = buf; + + while (len--) + __builtin_write8((volatile void __iomem *) __ioaddr, *bp++); +} + +static inline void io_outsw(unsigned int addr, const void *buf, int len) +{ + unsigned long __ioaddr = (unsigned long) addr; + const uint16_t *bp = buf; + + while (len--) + __builtin_write16((volatile void __iomem *) __ioaddr, (*bp++)); +} + +extern void __outsl_ns(unsigned int addr, const void *buf, int len); +extern void __outsl_sw(unsigned int addr, const void *buf, int len); +static inline void __outsl(unsigned int addr, const void *buf, int len, int swap) +{ + unsigned long __ioaddr = (unsigned long) addr; + + if (!swap) + __outsl_ns(__ioaddr, buf, len); + else + __outsl_sw(__ioaddr, buf, len); +} + +static inline void io_insb(unsigned long addr, void *buf, int len) +{ + uint8_t *bp = buf; + + while (len--) + *bp++ = __builtin_read8((volatile void __iomem *) addr); +} + +static inline void io_insw(unsigned long addr, void *buf, int len) +{ + uint16_t *bp = buf; + + while (len--) + *bp++ = __builtin_read16((volatile void __iomem *) addr); +} + +extern void __insl_ns(unsigned long addr, void *buf, int len); +extern void __insl_sw(unsigned long addr, void *buf, int len); +static inline void __insl(unsigned long addr, void *buf, int len, int swap) +{ + if (!swap) + __insl_ns(addr, buf, len); + else + __insl_sw(addr, buf, len); +} + +#define mmiowb() mb() + +/* + * make the short names macros so specific devices + * can override them as required + */ + +static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) +{ + memset((void __force *) addr, val, count); +} + +static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) +{ + memcpy(dst, (void __force *) src, count); +} + +static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count) +{ + memcpy((void __force *) dst, src, count); +} + +static inline uint8_t inb(unsigned long addr) +{ + return __builtin_read8((void __iomem *)addr); +} + +static inline uint16_t inw(unsigned long addr) +{ + uint16_t ret = __builtin_read16((void __iomem *)addr); + + if (__is_PCI_IO(addr)) + ret = _swapw(ret); + + return ret; +} + +static inline uint32_t inl(unsigned long addr) +{ + uint32_t ret = __builtin_read32((void __iomem *)addr); + + if (__is_PCI_IO(addr)) + ret = _swapl(ret); + + return ret; +} + +static inline void outb(uint8_t datum, unsigned long addr) +{ + __builtin_write8((void __iomem *)addr, datum); +} + +static inline void outw(uint16_t datum, unsigned long addr) +{ + if (__is_PCI_IO(addr)) + datum = _swapw(datum); + __builtin_write16((void __iomem *)addr, datum); +} + +static inline void outl(uint32_t datum, unsigned long addr) +{ + if (__is_PCI_IO(addr)) + datum = _swapl(datum); + __builtin_write32((void __iomem *)addr, datum); +} + +#define inb_p(addr) inb(addr) +#define inw_p(addr) inw(addr) +#define inl_p(addr) inl(addr) +#define outb_p(x,addr) outb(x,addr) +#define outw_p(x,addr) outw(x,addr) +#define outl_p(x,addr) outl(x,addr) + +#define outsb(a,b,l) io_outsb(a,b,l) +#define outsw(a,b,l) io_outsw(a,b,l) +#define outsl(a,b,l) __outsl(a,b,l,0) + +#define insb(a,b,l) io_insb(a,b,l) +#define insw(a,b,l) io_insw(a,b,l) +#define insl(a,b,l) __insl(a,b,l,0) + +#define IO_SPACE_LIMIT 0xffffffff + +static inline uint8_t readb(const volatile void __iomem *addr) +{ + return __builtin_read8((__force void volatile __iomem *) addr); +} + +static inline uint16_t readw(const volatile void __iomem *addr) +{ + uint16_t ret = __builtin_read16((__force void volatile __iomem *)addr); + + if (__is_PCI_MEM(addr)) + ret = _swapw(ret); + return ret; +} + +static inline uint32_t readl(const volatile void __iomem *addr) +{ + uint32_t ret = __builtin_read32((__force void volatile __iomem *)addr); + + if (__is_PCI_MEM(addr)) + ret = _swapl(ret); + + return ret; +} + +#define readb_relaxed readb +#define readw_relaxed readw +#define readl_relaxed readl + +static inline void writeb(uint8_t datum, volatile void __iomem *addr) +{ + __builtin_write8(addr, datum); + if (__is_PCI_MEM(addr)) + __flush_PCI_writes(); +} + +static inline void writew(uint16_t datum, volatile void __iomem *addr) +{ + if (__is_PCI_MEM(addr)) + datum = _swapw(datum); + + __builtin_write16(addr, datum); + if (__is_PCI_MEM(addr)) + __flush_PCI_writes(); +} + +static inline void writel(uint32_t datum, volatile void __iomem *addr) +{ + if (__is_PCI_MEM(addr)) + datum = _swapl(datum); + + __builtin_write32(addr, datum); + if (__is_PCI_MEM(addr)) + __flush_PCI_writes(); +} + + +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); + +static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +static inline void __iomem *ioremap_writethrough(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} + +static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +#define ioremap_wc ioremap_nocache + +extern void iounmap(void volatile __iomem *addr); + +static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return (void __iomem *) port; +} + +static inline void ioport_unmap(void __iomem *p) +{ +} + +static inline void flush_write_buffers(void) +{ + __asm__ __volatile__ ("membar" : : :"memory"); +} + +/* + * do appropriate I/O accesses for token type + */ +static inline unsigned int ioread8(void __iomem *p) +{ + return __builtin_read8(p); +} + +static inline unsigned int ioread16(void __iomem *p) +{ + uint16_t ret = __builtin_read16(p); + if (__is_PCI_addr(p)) + ret = _swapw(ret); + return ret; +} + +static inline unsigned int ioread32(void __iomem *p) +{ + uint32_t ret = __builtin_read32(p); + if (__is_PCI_addr(p)) + ret = _swapl(ret); + return ret; +} + +static inline void iowrite8(u8 val, void __iomem *p) +{ + __builtin_write8(p, val); + if (__is_PCI_MEM(p)) + __flush_PCI_writes(); +} + +static inline void iowrite16(u16 val, void __iomem *p) +{ + if (__is_PCI_addr(p)) + val = _swapw(val); + __builtin_write16(p, val); + if (__is_PCI_MEM(p)) + __flush_PCI_writes(); +} + +static inline void iowrite32(u32 val, void __iomem *p) +{ + if (__is_PCI_addr(p)) + val = _swapl(val); + __builtin_write32(p, val); + if (__is_PCI_MEM(p)) + __flush_PCI_writes(); +} + +static inline void ioread8_rep(void __iomem *p, void *dst, unsigned long count) +{ + io_insb((unsigned long) p, dst, count); +} + +static inline void ioread16_rep(void __iomem *p, void *dst, unsigned long count) +{ + io_insw((unsigned long) p, dst, count); +} + +static inline void ioread32_rep(void __iomem *p, void *dst, unsigned long count) +{ + __insl_ns((unsigned long) p, dst, count); +} + +static inline void iowrite8_rep(void __iomem *p, const void *src, unsigned long count) +{ + io_outsb((unsigned long) p, src, count); +} + +static inline void iowrite16_rep(void __iomem *p, const void *src, unsigned long count) +{ + io_outsw((unsigned long) p, src, count); +} + +static inline void iowrite32_rep(void __iomem *p, const void *src, unsigned long count) +{ + __outsl_ns((unsigned long) p, src, count); +} + +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ +struct pci_dev; +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); +static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) +{ +} + + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +#endif /* __KERNEL__ */ + +#endif /* _ASM_IO_H */ diff --git a/arch/frv/include/asm/ioctl.h b/arch/frv/include/asm/ioctl.h new file mode 100644 index 0000000..b279fe0 --- /dev/null +++ b/arch/frv/include/asm/ioctl.h @@ -0,0 +1 @@ +#include <asm-generic/ioctl.h> diff --git a/arch/frv/include/asm/ioctls.h b/arch/frv/include/asm/ioctls.h new file mode 100644 index 0000000..d0c30e3 --- /dev/null +++ b/arch/frv/include/asm/ioctls.h @@ -0,0 +1,86 @@ +#ifndef __ASM_IOCTLS_H__ +#define __ASM_IOCTLS_H__ + +#include <asm/ioctl.h> + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TCGETS2 _IOR('T',0x2A, struct termios2) +#define TCSETS2 _IOW('T',0x2B, struct termios2) +#define TCSETSW2 _IOW('T',0x2C, struct termios2) +#define TCSETSF2 _IOW('T',0x2D, struct termios2) +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define FIOQSIZE 0x545E + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* __ASM_IOCTLS_H__ */ + diff --git a/arch/frv/include/asm/ipcbuf.h b/arch/frv/include/asm/ipcbuf.h new file mode 100644 index 0000000..b546f67 --- /dev/null +++ b/arch/frv/include/asm/ipcbuf.h @@ -0,0 +1,30 @@ +#ifndef __ASM_IPCBUF_H__ +#define __ASM_IPCBUF_H__ + +/* + * The user_ipc_perm structure for FR-V architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* __ASM_IPCBUF_H__ */ + diff --git a/arch/frv/include/asm/irc-regs.h b/arch/frv/include/asm/irc-regs.h new file mode 100644 index 0000000..afa30ae --- /dev/null +++ b/arch/frv/include/asm/irc-regs.h @@ -0,0 +1,53 @@ +/* irc-regs.h: on-chip interrupt controller registers + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_IRC_REGS +#define _ASM_IRC_REGS + +#define __reg(ADDR) (*(volatile unsigned long *)(ADDR)) + +#define __get_TM0() ({ __reg(0xfeff9800); }) +#define __get_TM1() ({ __reg(0xfeff9808); }) +#define __set_TM1(V) do { __reg(0xfeff9808) = (V); mb(); } while(0) + +#define __set_TM1x(XI,V) \ +do { \ + int shift = (XI) * 2 + 16; \ + unsigned long tm1 = __reg(0xfeff9808); \ + tm1 &= ~(0x3 << shift); \ + tm1 |= (V) << shift; \ + __reg(0xfeff9808) = tm1; \ + mb(); \ +} while(0) + +#define __get_RS(C) ({ (__reg(0xfeff9810) >> ((C)+16)) & 1; }) + +#define __clr_RC(C) do { __reg(0xfeff9818) = 1 << ((C)+16); mb(); } while(0) + +#define __get_MASK(C) ({ (__reg(0xfeff9820) >> ((C)+16)) & 1; }) +#define __set_MASK(C) do { __reg(0xfeff9820) |= 1 << ((C)+16); mb(); } while(0) +#define __clr_MASK(C) do { __reg(0xfeff9820) &= ~(1 << ((C)+16)); mb(); } while(0) + +#define __get_MASK_all() __get_MASK(0) +#define __set_MASK_all() __set_MASK(0) +#define __clr_MASK_all() __clr_MASK(0) + +#define __get_IRL() ({ (__reg(0xfeff9828) >> 16) & 0xf; }) +#define __clr_IRL() do { __reg(0xfeff9828) = 0x100000; mb(); } while(0) + +#define __get_IRR(N) ({ __reg(0xfeff9840 + (N) * 8); }) +#define __set_IRR(N,V) do { __reg(0xfeff9840 + (N) * 8) = (V); } while(0) + +#define __get_IITMR(N) ({ __reg(0xfeff9880 + (N) * 8); }) +#define __set_IITMR(N,V) do { __reg(0xfeff9880 + (N) * 8) = (V); } while(0) + + +#endif /* _ASM_IRC_REGS */ diff --git a/arch/frv/include/asm/irq.h b/arch/frv/include/asm/irq.h new file mode 100644 index 0000000..3a66ebd --- /dev/null +++ b/arch/frv/include/asm/irq.h @@ -0,0 +1,30 @@ +/* irq.h: FRV IRQ definitions + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_IRQ_H_ +#define _ASM_IRQ_H_ + +#define NR_IRQS 48 +#define IRQ_BASE_CPU (0 * 16) +#define IRQ_BASE_FPGA (1 * 16) +#define IRQ_BASE_MB93493 (2 * 16) + +/* probe returns a 32-bit IRQ mask:-/ */ +#define MIN_PROBE_IRQ (NR_IRQS - 32) + +#ifndef __ASSEMBLY__ +static inline int irq_canonicalize(int irq) +{ + return irq; +} +#endif + +#endif /* _ASM_IRQ_H_ */ diff --git a/arch/frv/include/asm/irq_regs.h b/arch/frv/include/asm/irq_regs.h new file mode 100644 index 0000000..d22e832 --- /dev/null +++ b/arch/frv/include/asm/irq_regs.h @@ -0,0 +1,27 @@ +/* FRV per-CPU frame pointer holder + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_IRQ_REGS_H +#define _ASM_IRQ_REGS_H + +/* + * Per-cpu current frame pointer - the location of the last exception frame on + * the stack + * - on FRV, GR28 is dedicated to keeping a pointer to the current exception + * frame + */ +#define ARCH_HAS_OWN_IRQ_REGS + +#ifndef __ASSEMBLY__ +#define get_irq_regs() (__frame) +#endif + +#endif /* _ASM_IRQ_REGS_H */ diff --git a/arch/frv/include/asm/kdebug.h b/arch/frv/include/asm/kdebug.h new file mode 100644 index 0000000..6ece1b0 --- /dev/null +++ b/arch/frv/include/asm/kdebug.h @@ -0,0 +1 @@ +#include <asm-generic/kdebug.h> diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h new file mode 100644 index 0000000..f8e16b2 --- /dev/null +++ b/arch/frv/include/asm/kmap_types.h @@ -0,0 +1,29 @@ + +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +enum km_type { + /* arch specific kmaps - change the numbers attached to these at your peril */ + __KM_CACHE, /* cache flush page attachment point */ + __KM_PGD, /* current page directory */ + __KM_ITLB_PTD, /* current instruction TLB miss page table lookup */ + __KM_DTLB_PTD, /* current data TLB miss page table lookup */ + + /* general kmaps */ + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#endif diff --git a/arch/frv/include/asm/linkage.h b/arch/frv/include/asm/linkage.h new file mode 100644 index 0000000..636c1bc --- /dev/null +++ b/arch/frv/include/asm/linkage.h @@ -0,0 +1,7 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#define __ALIGN .align 4 +#define __ALIGN_STR ".align 4" + +#endif diff --git a/arch/frv/include/asm/local.h b/arch/frv/include/asm/local.h new file mode 100644 index 0000000..c27bdf0 --- /dev/null +++ b/arch/frv/include/asm/local.h @@ -0,0 +1,6 @@ +#ifndef _ASM_LOCAL_H +#define _ASM_LOCAL_H + +#include <asm-generic/local.h> + +#endif /* _ASM_LOCAL_H */ diff --git a/arch/frv/include/asm/math-emu.h b/arch/frv/include/asm/math-emu.h new file mode 100644 index 0000000..0c8f731 --- /dev/null +++ b/arch/frv/include/asm/math-emu.h @@ -0,0 +1,301 @@ +#ifndef _ASM_MATH_EMU_H +#define _ASM_MATH_EMU_H + +#include <asm/setup.h> +#include <linux/linkage.h> + +/* Status Register bits */ + +/* accrued exception bits */ +#define FPSR_AEXC_INEX 3 +#define FPSR_AEXC_DZ 4 +#define FPSR_AEXC_UNFL 5 +#define FPSR_AEXC_OVFL 6 +#define FPSR_AEXC_IOP 7 + +/* exception status bits */ +#define FPSR_EXC_INEX1 8 +#define FPSR_EXC_INEX2 9 +#define FPSR_EXC_DZ 10 +#define FPSR_EXC_UNFL 11 +#define FPSR_EXC_OVFL 12 +#define FPSR_EXC_OPERR 13 +#define FPSR_EXC_SNAN 14 +#define FPSR_EXC_BSUN 15 + +/* quotient byte, assumes big-endian, of course */ +#define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1)) + +/* condition code bits */ +#define FPSR_CC_NAN 24 +#define FPSR_CC_INF 25 +#define FPSR_CC_Z 26 +#define FPSR_CC_NEG 27 + + +/* Control register bits */ + +/* rounding mode */ +#define FPCR_ROUND_RN 0 /* round to nearest/even */ +#define FPCR_ROUND_RZ 1 /* round to zero */ +#define FPCR_ROUND_RM 2 /* minus infinity */ +#define FPCR_ROUND_RP 3 /* plus infinity */ + +/* rounding precision */ +#define FPCR_PRECISION_X 0 /* long double */ +#define FPCR_PRECISION_S 1 /* double */ +#define FPCR_PRECISION_D 2 /* float */ + + +/* Flags to select the debugging output */ +#define PDECODE 0 +#define PEXECUTE 1 +#define PCONV 2 +#define PNORM 3 +#define PREGISTER 4 +#define PINSTR 5 +#define PUNIMPL 6 +#define PMOVEM 7 + +#define PMDECODE (1<<PDECODE) +#define PMEXECUTE (1<<PEXECUTE) +#define PMCONV (1<<PCONV) +#define PMNORM (1<<PNORM) +#define PMREGISTER (1<<PREGISTER) +#define PMINSTR (1<<PINSTR) +#define PMUNIMPL (1<<PUNIMPL) +#define PMMOVEM (1<<PMOVEM) + +#ifndef __ASSEMBLY__ + +#include <linux/kernel.h> +#include <linux/sched.h> + +union fp_mant64 { + unsigned long long m64; + unsigned long m32[2]; +}; + +union fp_mant128 { + unsigned long long m64[2]; + unsigned long m32[4]; +}; + +/* internal representation of extended fp numbers */ +struct fp_ext { + unsigned char lowmant; + unsigned char sign; + unsigned short exp; + union fp_mant64 mant; +}; + +/* C representation of FPU registers */ +/* NOTE: if you change this, you have to change the assembler offsets + below and the size in <asm/fpu.h>, too */ +struct fp_data { + struct fp_ext fpreg[8]; + unsigned int fpcr; + unsigned int fpsr; + unsigned int fpiar; + unsigned short prec; + unsigned short rnd; + struct fp_ext temp[2]; +}; + +#if FPU_EMU_DEBUG +extern unsigned int fp_debugprint; + +#define dprint(bit, fmt, args...) ({ \ + if (fp_debugprint & (1 << (bit))) \ + printk(fmt, ## args); \ +}) +#else +#define dprint(bit, fmt, args...) +#endif + +#define uprint(str) ({ \ + static int __count = 3; \ + \ + if (__count > 0) { \ + printk("You just hit an unimplemented " \ + "fpu instruction (%s)\n", str); \ + printk("Please report this to ....\n"); \ + __count--; \ + } \ +}) + +#define FPDATA ((struct fp_data *)current->thread.fp) + +#else /* __ASSEMBLY__ */ + +#define FPDATA %a2 + +/* offsets from the base register to the floating point data in the task struct */ +#define FPD_FPREG (TASK_THREAD+THREAD_FPREG+0) +#define FPD_FPCR (TASK_THREAD+THREAD_FPREG+96) +#define FPD_FPSR (TASK_THREAD+THREAD_FPREG+100) +#define FPD_FPIAR (TASK_THREAD+THREAD_FPREG+104) +#define FPD_PREC (TASK_THREAD+THREAD_FPREG+108) +#define FPD_RND (TASK_THREAD+THREAD_FPREG+110) +#define FPD_TEMPFP1 (TASK_THREAD+THREAD_FPREG+112) +#define FPD_TEMPFP2 (TASK_THREAD+THREAD_FPREG+124) +#define FPD_SIZEOF (TASK_THREAD+THREAD_FPREG+136) + +/* offsets on the stack to access saved registers, + * these are only used during instruction decoding + * where we always know how deep we're on the stack. + */ +#define FPS_DO (PT_D0) +#define FPS_D1 (PT_D1) +#define FPS_D2 (PT_D2) +#define FPS_A0 (PT_A0) +#define FPS_A1 (PT_A1) +#define FPS_A2 (PT_A2) +#define FPS_SR (PT_SR) +#define FPS_PC (PT_PC) +#define FPS_EA (PT_PC+6) +#define FPS_PC2 (PT_PC+10) + +.macro fp_get_fp_reg + lea (FPD_FPREG,FPDATA,%d0.w*4),%a0 + lea (%a0,%d0.w*8),%a0 +.endm + +/* Macros used to get/put the current program counter. + * 020/030 use a different stack frame then 040/060, for the + * 040/060 the return pc points already to the next location, + * so this only needs to be modified for jump instructions. + */ +.macro fp_get_pc dest + move.l (FPS_PC+4,%sp),\dest +.endm + +.macro fp_put_pc src,jump=0 + move.l \src,(FPS_PC+4,%sp) +.endm + +.macro fp_get_instr_data f,s,dest,label + getuser \f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4) + addq.l #\s,%sp@(FPS_PC+4) +.endm + +.macro fp_get_instr_word dest,label,addr + fp_get_instr_data w,2,\dest,\label,\addr +.endm + +.macro fp_get_instr_long dest,label,addr + fp_get_instr_data l,4,\dest,\label,\addr +.endm + +/* These macros are used to read from/write to user space + * on error we jump to the fixup section, load the fault + * address into %a0 and jump to the exit. + * (derived from <asm/uaccess.h>) + */ +.macro getuser size,src,dest,label,addr +| printf ,"[\size<%08x]",1,\addr +.Lu1\@: moves\size \src,\dest + + .section .fixup,"ax" + .even +.Lu2\@: move.l \addr,%a0 + jra \label + .previous + + .section __ex_table,"a" + .align 4 + .long .Lu1\@,.Lu2\@ + .previous +.endm + +.macro putuser size,src,dest,label,addr +| printf ,"[\size>%08x]",1,\addr +.Lu1\@: moves\size \src,\dest +.Lu2\@: + + .section .fixup,"ax" + .even +.Lu3\@: move.l \addr,%a0 + jra \label + .previous + + .section __ex_table,"a" + .align 4 + .long .Lu1\@,.Lu3\@ + .long .Lu2\@,.Lu3\@ + .previous +.endm + + +.macro movestack nr,arg1,arg2,arg3,arg4,arg5 + .if \nr + movestack (\nr-1),\arg2,\arg3,\arg4,\arg5 + move.l \arg1,-(%sp) + .endif +.endm + +.macro printf bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5 +#ifdef FPU_EMU_DEBUG + .data +.Lpdata\@: + .string "\string" + .previous + + movem.l %d0/%d1/%a0/%a1,-(%sp) + .if \bit+1 +#if 0 + moveq #\bit,%d0 + andw #7,%d0 + btst %d0,fp_debugprint+((31-\bit)/8) +#else + btst #\bit,fp_debugprint+((31-\bit)/8) +#endif + jeq .Lpskip\@ + .endif + movestack \nr,\arg1,\arg2,\arg3,\arg4,\arg5 + pea .Lpdata\@ + jsr printk + lea ((\nr+1)*4,%sp),%sp +.Lpskip\@: + movem.l (%sp)+,%d0/%d1/%a0/%a1 +#endif +.endm + +.macro printx bit,fp +#ifdef FPU_EMU_DEBUG + movem.l %d0/%a0,-(%sp) + lea \fp,%a0 +#if 0 + moveq #'+',%d0 + tst.w (%a0) + jeq .Lx1\@ + moveq #'-',%d0 +.Lx1\@: printf \bit," %c",1,%d0 + move.l (4,%a0),%d0 + bclr #31,%d0 + jne .Lx2\@ + printf \bit,"0." + jra .Lx3\@ +.Lx2\@: printf \bit,"1." +.Lx3\@: printf \bit,"%08x%08x",2,%d0,%a0@(8) + move.w (2,%a0),%d0 + ext.l %d0 + printf \bit,"E%04x",1,%d0 +#else + printf \bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8) +#endif + movem.l (%sp)+,%d0/%a0 +#endif +.endm + +.macro debug instr,args +#ifdef FPU_EMU_DEBUG + \instr \args +#endif +.endm + + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_FRV_MATH_EMU_H */ + diff --git a/arch/frv/include/asm/mb-regs.h b/arch/frv/include/asm/mb-regs.h new file mode 100644 index 0000000..219e5f9 --- /dev/null +++ b/arch/frv/include/asm/mb-regs.h @@ -0,0 +1,200 @@ +/* mb-regs.h: motherboard registers + * + * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MB_REGS_H +#define _ASM_MB_REGS_H + +#include <asm/cpu-irqs.h> +#include <asm/sections.h> +#include <asm/mem-layout.h> + +#ifndef __ASSEMBLY__ +/* gcc builtins, annotated */ + +unsigned long __builtin_read8(volatile void __iomem *); +unsigned long __builtin_read16(volatile void __iomem *); +unsigned long __builtin_read32(volatile void __iomem *); +void __builtin_write8(volatile void __iomem *, unsigned char); +void __builtin_write16(volatile void __iomem *, unsigned short); +void __builtin_write32(volatile void __iomem *, unsigned long); +#endif + +#define __region_IO KERNEL_IO_START /* the region from 0xe0000000 to 0xffffffff has suitable + * protection laid over the top for use in memory-mapped + * I/O + */ + +#define __region_CS0 0xff000000 /* Boot ROMs area */ + +#ifdef CONFIG_MB93091_VDK +/* + * VDK motherboard and CPU card specific stuff + */ + +#include <asm/mb93091-fpga-irqs.h> + +#define IRQ_CPU_MB93493_0 IRQ_CPU_EXTERNAL0 +#define IRQ_CPU_MB93493_1 IRQ_CPU_EXTERNAL1 + +#define __region_CS2 0xe0000000 /* SLBUS/PCI I/O space */ +#define __region_CS2_M 0x0fffffff /* mask */ +#define __region_CS2_C 0x00000000 /* control */ +#define __region_CS5 0xf0000000 /* MB93493 CSC area (DAV daughter board) */ +#define __region_CS5_M 0x00ffffff +#define __region_CS5_C 0x00010000 +#define __region_CS7 0xf1000000 /* CB70 CPU-card PCMCIA port I/O space */ +#define __region_CS7_M 0x00ffffff +#define __region_CS7_C 0x00410701 +#define __region_CS1 0xfc000000 /* SLBUS/PCI bridge control registers */ +#define __region_CS1_M 0x000fffff +#define __region_CS1_C 0x00000000 +#define __region_CS6 0xfc100000 /* CB70 CPU-card DM9000 LAN I/O space */ +#define __region_CS6_M 0x000fffff +#define __region_CS6_C 0x00400707 +#define __region_CS3 0xfc200000 /* MB93493 CSR area (DAV daughter board) */ +#define __region_CS3_M 0x000fffff +#define __region_CS3_C 0xc8100000 +#define __region_CS4 0xfd000000 /* CB70 CPU-card extra flash space */ +#define __region_CS4_M 0x00ffffff +#define __region_CS4_C 0x00000f07 + +#define __region_PCI_IO (__region_CS2 + 0x04000000UL) +#define __region_PCI_MEM (__region_CS2 + 0x08000000UL) +#define __flush_PCI_writes() \ +do { \ + __builtin_write8((volatile void __iomem *) __region_PCI_MEM, 0); \ +} while(0) + +#define __is_PCI_IO(addr) \ + (((unsigned long)(addr) >> 24) - (__region_PCI_IO >> 24) < (0x04000000UL >> 24)) + +#define __is_PCI_MEM(addr) \ + ((unsigned long)(addr) - __region_PCI_MEM < 0x08000000UL) + +#define __is_PCI_addr(addr) \ + ((unsigned long)(addr) - __region_PCI_IO < 0x0c000000UL) + +#define __get_CLKSW() ({ *(volatile unsigned long *)(__region_CS2 + 0x0130000cUL) & 0xffUL; }) +#define __get_CLKIN() (__get_CLKSW() * 125U * 100000U / 24U) + +#ifndef __ASSEMBLY__ +extern int __nongprelbss mb93090_mb00_detected; +#endif + +#define __addr_LEDS() (__region_CS2 + 0x01200004UL) +#ifdef CONFIG_MB93090_MB00 +#define __set_LEDS(X) \ +do { \ + if (mb93090_mb00_detected) \ + __builtin_write32((void __iomem *) __addr_LEDS(), ~(X)); \ +} while (0) +#else +#define __set_LEDS(X) +#endif + +#define __addr_LCD() (__region_CS2 + 0x01200008UL) +#define __get_LCD(B) __builtin_read32((volatile void __iomem *) (B)) +#define __set_LCD(B,X) __builtin_write32((volatile void __iomem *) (B), (X)) + +#define LCD_D 0x000000ff /* LCD data bus */ +#define LCD_RW 0x00000100 /* LCD R/W signal */ +#define LCD_RS 0x00000200 /* LCD Register Select */ +#define LCD_E 0x00000400 /* LCD Start Enable Signal */ + +#define LCD_CMD_CLEAR (LCD_E|0x001) +#define LCD_CMD_HOME (LCD_E|0x002) +#define LCD_CMD_CURSOR_INC (LCD_E|0x004) +#define LCD_CMD_SCROLL_INC (LCD_E|0x005) +#define LCD_CMD_CURSOR_DEC (LCD_E|0x006) +#define LCD_CMD_SCROLL_DEC (LCD_E|0x007) +#define LCD_CMD_OFF (LCD_E|0x008) +#define LCD_CMD_ON(CRSR,BLINK) (LCD_E|0x00c|(CRSR<<1)|BLINK) +#define LCD_CMD_CURSOR_MOVE_L (LCD_E|0x010) +#define LCD_CMD_CURSOR_MOVE_R (LCD_E|0x014) +#define LCD_CMD_DISPLAY_SHIFT_L (LCD_E|0x018) +#define LCD_CMD_DISPLAY_SHIFT_R (LCD_E|0x01c) +#define LCD_CMD_FUNCSET(DL,N,F) (LCD_E|0x020|(DL<<4)|(N<<3)|(F<<2)) +#define LCD_CMD_SET_CG_ADDR(X) (LCD_E|0x040|X) +#define LCD_CMD_SET_DD_ADDR(X) (LCD_E|0x080|X) +#define LCD_CMD_READ_BUSY (LCD_E|LCD_RW) +#define LCD_DATA_WRITE(X) (LCD_E|LCD_RS|(X)) +#define LCD_DATA_READ (LCD_E|LCD_RS|LCD_RW) + +#else +/* + * PDK unit specific stuff + */ + +#include <asm/mb93093-fpga-irqs.h> + +#define IRQ_CPU_MB93493_0 IRQ_CPU_EXTERNAL0 +#define IRQ_CPU_MB93493_1 IRQ_CPU_EXTERNAL1 + +#define __region_CS5 0xf0000000 /* MB93493 CSC area (DAV daughter board) */ +#define __region_CS5_M 0x00ffffff /* mask */ +#define __region_CS5_C 0x00010000 /* control */ +#define __region_CS2 0x20000000 /* FPGA registers */ +#define __region_CS2_M 0x000fffff +#define __region_CS2_C 0x00000000 +#define __region_CS1 0xfc100000 /* LAN registers */ +#define __region_CS1_M 0x000fffff +#define __region_CS1_C 0x00010404 +#define __region_CS3 0xfc200000 /* MB93493 CSR area (DAV daughter board) */ +#define __region_CS3_M 0x000fffff +#define __region_CS3_C 0xc8000000 +#define __region_CS4 0xfd000000 /* extra ROMs area */ +#define __region_CS4_M 0x00ffffff +#define __region_CS4_C 0x00000f07 + +#define __region_CS6 0xfe000000 /* not used - hide behind CPU resource I/O regs */ +#define __region_CS6_M 0x000fffff +#define __region_CS6_C 0x00000f07 +#define __region_CS7 0xfe000000 /* not used - hide behind CPU resource I/O regs */ +#define __region_CS7_M 0x000fffff +#define __region_CS7_C 0x00000f07 + +#define __is_PCI_IO(addr) 0 /* no PCI */ +#define __is_PCI_MEM(addr) 0 +#define __is_PCI_addr(addr) 0 +#define __region_PCI_IO 0 +#define __region_PCI_MEM 0 +#define __flush_PCI_writes() do { } while(0) + +#define __get_CLKSW() 0UL +#define __get_CLKIN() 66000000UL + +#define __addr_LEDS() (__region_CS2 + 0x00000023UL) +#define __set_LEDS(X) __builtin_write8((volatile void __iomem *) __addr_LEDS(), (X)) + +#define __addr_FPGATR() (__region_CS2 + 0x00000030UL) +#define __set_FPGATR(X) __builtin_write32((volatile void __iomem *) __addr_FPGATR(), (X)) +#define __get_FPGATR() __builtin_read32((volatile void __iomem *) __addr_FPGATR()) + +#define MB93093_FPGA_FPGATR_AUDIO_CLK 0x00000003 + +#define __set_FPGATR_AUDIO_CLK(V) \ + __set_FPGATR((__get_FPGATR() & ~MB93093_FPGA_FPGATR_AUDIO_CLK) | (V)) + +#define MB93093_FPGA_FPGATR_AUDIO_CLK_OFF 0x0 +#define MB93093_FPGA_FPGATR_AUDIO_CLK_11MHz 0x1 +#define MB93093_FPGA_FPGATR_AUDIO_CLK_12MHz 0x2 +#define MB93093_FPGA_FPGATR_AUDIO_CLK_02MHz 0x3 + +#define MB93093_FPGA_SWR_PUSHSWMASK (0x1F<<26) +#define MB93093_FPGA_SWR_PUSHSW4 (1<<29) + +#define __addr_FPGA_SWR ((volatile void __iomem *)(__region_CS2 + 0x28UL)) +#define __get_FPGA_PUSHSW1_5() (__builtin_read32(__addr_FPGA_SWR) & MB93093_FPGA_SWR_PUSHSWMASK) + + +#endif + +#endif /* _ASM_MB_REGS_H */ diff --git a/arch/frv/include/asm/mb86943a.h b/arch/frv/include/asm/mb86943a.h new file mode 100644 index 0000000..e87ef92 --- /dev/null +++ b/arch/frv/include/asm/mb86943a.h @@ -0,0 +1,42 @@ +/* mb86943a.h: MB86943 SPARClite <-> PCI bridge registers + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MB86943A_H +#define _ASM_MB86943A_H + +#include <asm/mb-regs.h> + +#define __reg_MB86943_sl_ctl *(volatile uint32_t *) (__region_CS1 + 0x00) + +#define MB86943_SL_CTL_BUS_WIDTH_64 0x00000001 +#define MB86943_SL_CTL_AS_HOST 0x00000002 +#define MB86943_SL_CTL_DRCT_MASTER_SWAP 0x00000004 +#define MB86943_SL_CTL_DRCT_SLAVE_SWAP 0x00000008 +#define MB86943_SL_CTL_PCI_CONFIG_SWAP 0x00000010 +#define MB86943_SL_CTL_ECS0_ENABLE 0x00000020 +#define MB86943_SL_CTL_ECS1_ENABLE 0x00000040 +#define MB86943_SL_CTL_ECS2_ENABLE 0x00000080 + +#define __reg_MB86943_ecs_ctl(N) *(volatile uint32_t *) (__region_CS1 + 0x08 + (0x08*(N))) +#define __reg_MB86943_ecs_range(N) *(volatile uint32_t *) (__region_CS1 + 0x20 + (0x10*(N))) +#define __reg_MB86943_ecs_base(N) *(volatile uint32_t *) (__region_CS1 + 0x28 + (0x10*(N))) + +#define __reg_MB86943_sl_pci_io_range *(volatile uint32_t *) (__region_CS1 + 0x50) +#define __reg_MB86943_sl_pci_io_base *(volatile uint32_t *) (__region_CS1 + 0x58) +#define __reg_MB86943_sl_pci_mem_range *(volatile uint32_t *) (__region_CS1 + 0x60) +#define __reg_MB86943_sl_pci_mem_base *(volatile uint32_t *) (__region_CS1 + 0x68) +#define __reg_MB86943_pci_sl_io_base *(volatile uint32_t *) (__region_CS1 + 0x70) +#define __reg_MB86943_pci_sl_mem_base *(volatile uint32_t *) (__region_CS1 + 0x78) + +#define __reg_MB86943_pci_arbiter *(volatile uint32_t *) (__region_CS2 + 0x01300014) +#define MB86943_PCIARB_EN 0x00000001 + +#endif /* _ASM_MB86943A_H */ diff --git a/arch/frv/include/asm/mb93091-fpga-irqs.h b/arch/frv/include/asm/mb93091-fpga-irqs.h new file mode 100644 index 0000000..19778c5b --- /dev/null +++ b/arch/frv/include/asm/mb93091-fpga-irqs.h @@ -0,0 +1,42 @@ +/* mb93091-fpga-irqs.h: MB93091 CPU board FPGA IRQs + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MB93091_FPGA_IRQS_H +#define _ASM_MB93091_FPGA_IRQS_H + +#include <asm/irq.h> + +#ifndef __ASSEMBLY__ + +/* IRQ IDs presented to drivers */ +enum { + IRQ_FPGA__UNUSED = IRQ_BASE_FPGA, + IRQ_FPGA_SYSINT_BUS_EXPANSION_1, + IRQ_FPGA_SL_BUS_EXPANSION_2, + IRQ_FPGA_PCI_INTD, + IRQ_FPGA_PCI_INTC, + IRQ_FPGA_PCI_INTB, + IRQ_FPGA_PCI_INTA, + IRQ_FPGA_SL_BUS_EXPANSION_7, + IRQ_FPGA_SYSINT_BUS_EXPANSION_8, + IRQ_FPGA_SL_BUS_EXPANSION_9, + IRQ_FPGA_MB86943_PCI_INTA, + IRQ_FPGA_MB86943_SLBUS_SIDE, + IRQ_FPGA_RTL8029_INTA, + IRQ_FPGA_SYSINT_BUS_EXPANSION_13, + IRQ_FPGA_SL_BUS_EXPANSION_14, + IRQ_FPGA_NMI, +}; + + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_MB93091_FPGA_IRQS_H */ diff --git a/arch/frv/include/asm/mb93093-fpga-irqs.h b/arch/frv/include/asm/mb93093-fpga-irqs.h new file mode 100644 index 0000000..590266b --- /dev/null +++ b/arch/frv/include/asm/mb93093-fpga-irqs.h @@ -0,0 +1,29 @@ +/* mb93093-fpga-irqs.h: MB93093 CPU board FPGA IRQs + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MB93093_FPGA_IRQS_H +#define _ASM_MB93093_FPGA_IRQS_H + +#include <asm/irq.h> + +#ifndef __ASSEMBLY__ + +/* IRQ IDs presented to drivers */ +enum { + IRQ_FPGA_PUSH_BUTTON_SW1_5 = IRQ_BASE_FPGA + 8, + IRQ_FPGA_ROCKER_C_SW8 = IRQ_BASE_FPGA + 9, + IRQ_FPGA_ROCKER_C_SW9 = IRQ_BASE_FPGA + 10, +}; + + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_MB93093_FPGA_IRQS_H */ diff --git a/arch/frv/include/asm/mb93493-irqs.h b/arch/frv/include/asm/mb93493-irqs.h new file mode 100644 index 0000000..82c7aed --- /dev/null +++ b/arch/frv/include/asm/mb93493-irqs.h @@ -0,0 +1,50 @@ +/* mb93493-irqs.h: MB93493 companion chip IRQs + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MB93493_IRQS_H +#define _ASM_MB93493_IRQS_H + +#include <asm/irq.h> + +#ifndef __ASSEMBLY__ + +/* IRQ IDs presented to drivers */ +enum { + IRQ_MB93493_VDC = IRQ_BASE_MB93493 + 0, + IRQ_MB93493_VCC = IRQ_BASE_MB93493 + 1, + IRQ_MB93493_AUDIO_OUT = IRQ_BASE_MB93493 + 2, + IRQ_MB93493_I2C_0 = IRQ_BASE_MB93493 + 3, + IRQ_MB93493_I2C_1 = IRQ_BASE_MB93493 + 4, + IRQ_MB93493_USB = IRQ_BASE_MB93493 + 5, + IRQ_MB93493_LOCAL_BUS = IRQ_BASE_MB93493 + 7, + IRQ_MB93493_PCMCIA = IRQ_BASE_MB93493 + 8, + IRQ_MB93493_GPIO = IRQ_BASE_MB93493 + 9, + IRQ_MB93493_AUDIO_IN = IRQ_BASE_MB93493 + 10, +}; + +/* IRQ multiplexor mappings */ +#define ROUTE_VIA_IRQ0 0 /* route IRQ by way of CPU external IRQ 0 */ +#define ROUTE_VIA_IRQ1 1 /* route IRQ by way of CPU external IRQ 1 */ + +#define IRQ_MB93493_VDC_ROUTE ROUTE_VIA_IRQ0 +#define IRQ_MB93493_VCC_ROUTE ROUTE_VIA_IRQ1 +#define IRQ_MB93493_AUDIO_OUT_ROUTE ROUTE_VIA_IRQ1 +#define IRQ_MB93493_I2C_0_ROUTE ROUTE_VIA_IRQ1 +#define IRQ_MB93493_I2C_1_ROUTE ROUTE_VIA_IRQ1 +#define IRQ_MB93493_USB_ROUTE ROUTE_VIA_IRQ1 +#define IRQ_MB93493_LOCAL_BUS_ROUTE ROUTE_VIA_IRQ1 +#define IRQ_MB93493_PCMCIA_ROUTE ROUTE_VIA_IRQ1 +#define IRQ_MB93493_GPIO_ROUTE ROUTE_VIA_IRQ1 +#define IRQ_MB93493_AUDIO_IN_ROUTE ROUTE_VIA_IRQ1 + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_MB93493_IRQS_H */ diff --git a/arch/frv/include/asm/mb93493-regs.h b/arch/frv/include/asm/mb93493-regs.h new file mode 100644 index 0000000..8a1f6aa --- /dev/null +++ b/arch/frv/include/asm/mb93493-regs.h @@ -0,0 +1,281 @@ +/* mb93493-regs.h: MB93493 companion chip registers + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MB93493_REGS_H +#define _ASM_MB93493_REGS_H + +#include <asm/mb-regs.h> +#include <asm/mb93493-irqs.h> + +#define __addr_MB93493(X) ((volatile unsigned long *)(__region_CS3 + (X))) +#define __get_MB93493(X) ({ *(volatile unsigned long *)(__region_CS3 + (X)); }) + +#define __set_MB93493(X,V) \ +do { \ + *(volatile unsigned long *)(__region_CS3 + (X)) = (V); mb(); \ +} while(0) + +#define __get_MB93493_STSR(X) __get_MB93493(0x3c0 + (X) * 4) +#define __set_MB93493_STSR(X,V) __set_MB93493(0x3c0 + (X) * 4, (V)) +#define MB93493_STSR_EN + +#define __addr_MB93493_IQSR(X) __addr_MB93493(0x3d0 + (X) * 4) +#define __get_MB93493_IQSR(X) __get_MB93493(0x3d0 + (X) * 4) +#define __set_MB93493_IQSR(X,V) __set_MB93493(0x3d0 + (X) * 4, (V)) + +#define __get_MB93493_DQSR(X) __get_MB93493(0x3e0 + (X) * 4) +#define __set_MB93493_DQSR(X,V) __set_MB93493(0x3e0 + (X) * 4, (V)) + +#define __get_MB93493_LBSER() __get_MB93493(0x3f0) +#define __set_MB93493_LBSER(V) __set_MB93493(0x3f0, (V)) + +#define MB93493_LBSER_VDC 0x00010000 +#define MB93493_LBSER_VCC 0x00020000 +#define MB93493_LBSER_AUDIO 0x00040000 +#define MB93493_LBSER_I2C_0 0x00080000 +#define MB93493_LBSER_I2C_1 0x00100000 +#define MB93493_LBSER_USB 0x00200000 +#define MB93493_LBSER_GPIO 0x00800000 +#define MB93493_LBSER_PCMCIA 0x01000000 + +#define __get_MB93493_LBSR() __get_MB93493(0x3fc) +#define __set_MB93493_LBSR(V) __set_MB93493(0x3fc, (V)) + +/* + * video display controller + */ +#define __get_MB93493_VDC(X) __get_MB93493(MB93493_VDC_##X) +#define __set_MB93493_VDC(X,V) __set_MB93493(MB93493_VDC_##X, (V)) + +#define MB93493_VDC_RCURSOR 0x140 /* cursor position */ +#define MB93493_VDC_RCT1 0x144 /* cursor colour 1 */ +#define MB93493_VDC_RCT2 0x148 /* cursor colour 2 */ +#define MB93493_VDC_RHDC 0x150 /* horizontal display period */ +#define MB93493_VDC_RH_MARGINS 0x154 /* horizontal margin sizes */ +#define MB93493_VDC_RVDC 0x158 /* vertical display period */ +#define MB93493_VDC_RV_MARGINS 0x15c /* vertical margin sizes */ +#define MB93493_VDC_RC 0x170 /* VDC control */ +#define MB93493_VDC_RCLOCK 0x174 /* clock divider, DMA req delay */ +#define MB93493_VDC_RBLACK 0x178 /* black insert sizes */ +#define MB93493_VDC_RS 0x17c /* VDC status */ + +#define __addr_MB93493_VDC_BCI(X) ({ (volatile unsigned long *)(__region_CS3 + 0x000 + (X)); }) +#define __addr_MB93493_VDC_TPO(X) (__region_CS3 + 0x1c0 + (X)) + +#define VDC_TPO_WIDTH 32 + +#define VDC_RC_DSR 0x00000080 /* VDC master reset */ + +#define VDC_RS_IT 0x00060000 /* interrupt indicators */ +#define VDC_RS_IT_UNDERFLOW 0x00040000 /* - underflow event */ +#define VDC_RS_IT_VSYNC 0x00020000 /* - VSYNC event */ +#define VDC_RS_DFI 0x00010000 /* current interlace field number */ +#define VDC_RS_DFI_TOP 0x00000000 /* - top field */ +#define VDC_RS_DFI_BOTTOM 0x00010000 /* - bottom field */ +#define VDC_RS_DCSR 0x00000010 /* cursor state */ +#define VDC_RS_DCM 0x00000003 /* display mode */ +#define VDC_RS_DCM_DISABLED 0x00000000 /* - display disabled */ +#define VDC_RS_DCM_STOPPED 0x00000001 /* - VDC stopped */ +#define VDC_RS_DCM_FREERUNNING 0x00000002 /* - VDC free-running */ +#define VDC_RS_DCM_TRANSFERRING 0x00000003 /* - data being transferred to VDC */ + +/* + * video capture controller + */ +#define __get_MB93493_VCC(X) __get_MB93493(MB93493_VCC_##X) +#define __set_MB93493_VCC(X,V) __set_MB93493(MB93493_VCC_##X, (V)) + +#define MB93493_VCC_RREDUCT 0x104 /* reduction rate */ +#define MB93493_VCC_RHY 0x108 /* horizontal brightness filter coefficients */ +#define MB93493_VCC_RHC 0x10c /* horizontal colour-difference filter coefficients */ +#define MB93493_VCC_RHSIZE 0x110 /* horizontal cycle sizes */ +#define MB93493_VCC_RHBC 0x114 /* horizontal back porch size */ +#define MB93493_VCC_RVCC 0x118 /* vertical capture period */ +#define MB93493_VCC_RVBC 0x11c /* vertical back porch period */ +#define MB93493_VCC_RV 0x120 /* vertical filter coefficients */ +#define MB93493_VCC_RDTS 0x128 /* DMA transfer size */ +#define MB93493_VCC_RDTS_4B 0x01000000 /* 4-byte transfer */ +#define MB93493_VCC_RDTS_32B 0x03000000 /* 32-byte transfer */ +#define MB93493_VCC_RDTS_SHIFT 24 +#define MB93493_VCC_RCC 0x130 /* VCC control */ +#define MB93493_VCC_RIS 0x134 /* VCC interrupt status */ + +#define __addr_MB93493_VCC_TPI(X) (__region_CS3 + 0x180 + (X)) + +#define VCC_RHSIZE_RHCC 0x000007ff +#define VCC_RHSIZE_RHCC_SHIFT 0 +#define VCC_RHSIZE_RHTCC 0x0fff0000 +#define VCC_RHSIZE_RHTCC_SHIFT 16 + +#define VCC_RVBC_RVBC 0x00003f00 +#define VCC_RVBC_RVBC_SHIFT 8 + +#define VCC_RREDUCT_RHR 0x07ff0000 +#define VCC_RREDUCT_RHR_SHIFT 16 +#define VCC_RREDUCT_RVR 0x000007ff +#define VCC_RREDUCT_RVR_SHIFT 0 + +#define VCC_RCC_CE 0x00000001 /* VCC enable */ +#define VCC_RCC_CS 0x00000002 /* request video capture start */ +#define VCC_RCC_CPF 0x0000000c /* pixel format */ +#define VCC_RCC_CPF_YCBCR_16 0x00000000 /* - YCbCr 4:2:2 16-bit format */ +#define VCC_RCC_CPF_RGB 0x00000004 /* - RGB 4:4:4 format */ +#define VCC_RCC_CPF_YCBCR_24 0x00000008 /* - YCbCr 4:2:2 24-bit format */ +#define VCC_RCC_CPF_BT656 0x0000000c /* - ITU R-BT.656 format */ +#define VCC_RCC_CPF_SHIFT 2 +#define VCC_RCC_CSR 0x00000080 /* request reset */ +#define VCC_RCC_HSIP 0x00000100 /* HSYNC polarity */ +#define VCC_RCC_HSIP_LOACT 0x00000000 /* - low active */ +#define VCC_RCC_HSIP_HIACT 0x00000100 /* - high active */ +#define VCC_RCC_VSIP 0x00000200 /* VSYNC polarity */ +#define VCC_RCC_VSIP_LOACT 0x00000000 /* - low active */ +#define VCC_RCC_VSIP_HIACT 0x00000200 /* - high active */ +#define VCC_RCC_CIE 0x00000800 /* interrupt enable */ +#define VCC_RCC_CFP 0x00001000 /* RGB pixel packing */ +#define VCC_RCC_CFP_4TO3 0x00000000 /* - pack 4 pixels into 3 words */ +#define VCC_RCC_CFP_1TO1 0x00001000 /* - pack 1 pixel into 1 words */ +#define VCC_RCC_CSM 0x00006000 /* interlace specification */ +#define VCC_RCC_CSM_ONEPASS 0x00002000 /* - non-interlaced */ +#define VCC_RCC_CSM_INTERLACE 0x00004000 /* - interlaced */ +#define VCC_RCC_CSM_SHIFT 13 +#define VCC_RCC_ES 0x00008000 /* capture start polarity */ +#define VCC_RCC_ES_NEG 0x00000000 /* - negative edge */ +#define VCC_RCC_ES_POS 0x00008000 /* - positive edge */ +#define VCC_RCC_IFI 0x00080000 /* inferlace field evaluation reverse */ +#define VCC_RCC_FDTS 0x00300000 /* interlace field start */ +#define VCC_RCC_FDTS_3_8 0x00000000 /* - 3/8 of horizontal entire cycle */ +#define VCC_RCC_FDTS_1_4 0x00100000 /* - 1/4 of horizontal entire cycle */ +#define VCC_RCC_FDTS_7_16 0x00200000 /* - 7/16 of horizontal entire cycle */ +#define VCC_RCC_FDTS_SHIFT 20 +#define VCC_RCC_MOV 0x00400000 /* test bit - always set to 1 */ +#define VCC_RCC_STP 0x00800000 /* request video capture stop */ +#define VCC_RCC_TO 0x01000000 /* input during top-field only */ + +#define VCC_RIS_VSYNC 0x01000000 /* VSYNC interrupt */ +#define VCC_RIS_OV 0x02000000 /* overflow interrupt */ +#define VCC_RIS_BOTTOM 0x08000000 /* interlace bottom field */ +#define VCC_RIS_STARTED 0x10000000 /* capture started */ + +/* + * I2C + */ +#define MB93493_I2C_BSR 0x340 /* bus status */ +#define MB93493_I2C_BCR 0x344 /* bus control */ +#define MB93493_I2C_CCR 0x348 /* clock control */ +#define MB93493_I2C_ADR 0x34c /* address */ +#define MB93493_I2C_DTR 0x350 /* data */ +#define MB93493_I2C_BC2R 0x35c /* bus control 2 */ + +#define __addr_MB93493_I2C(port,X) (__region_CS3 + MB93493_I2C_##X + ((port)*0x20)) +#define __get_MB93493_I2C(port,X) __get_MB93493(MB93493_I2C_##X + ((port)*0x20)) +#define __set_MB93493_I2C(port,X,V) __set_MB93493(MB93493_I2C_##X + ((port)*0x20), (V)) + +#define I2C_BSR_BB (1 << 7) + +/* + * audio controller (I2S) registers + */ +#define __get_MB93493_I2S(X) __get_MB93493(MB93493_I2S_##X) +#define __set_MB93493_I2S(X,V) __set_MB93493(MB93493_I2S_##X, (V)) + +#define MB93493_I2S_ALDR 0x300 /* L-channel data */ +#define MB93493_I2S_ARDR 0x304 /* R-channel data */ +#define MB93493_I2S_APDR 0x308 /* 16-bit packed data */ +#define MB93493_I2S_AISTR 0x310 /* status */ +#define MB93493_I2S_AICR 0x314 /* control */ + +#define __addr_MB93493_I2S_ALDR(X) (__region_CS3 + MB93493_I2S_ALDR + (X)) +#define __addr_MB93493_I2S_ARDR(X) (__region_CS3 + MB93493_I2S_ARDR + (X)) +#define __addr_MB93493_I2S_APDR(X) (__region_CS3 + MB93493_I2S_APDR + (X)) +#define __addr_MB93493_I2S_ADR(X) (__region_CS3 + 0x320 + (X)) + +#define I2S_AISTR_OTST 0x00000003 /* status of output data transfer */ +#define I2S_AISTR_OTR 0x00000010 /* output transfer request pending */ +#define I2S_AISTR_OUR 0x00000020 /* output FIFO underrun detected */ +#define I2S_AISTR_OOR 0x00000040 /* output FIFO overrun detected */ +#define I2S_AISTR_ODS 0x00000100 /* output DMA transfer size */ +#define I2S_AISTR_ODE 0x00000400 /* output DMA transfer request enable */ +#define I2S_AISTR_OTRIE 0x00001000 /* output transfer request interrupt enable */ +#define I2S_AISTR_OURIE 0x00002000 /* output FIFO underrun interrupt enable */ +#define I2S_AISTR_OORIE 0x00004000 /* output FIFO overrun interrupt enable */ +#define I2S_AISTR__OUT_MASK 0x00007570 +#define I2S_AISTR_ITST 0x00030000 /* status of input data transfer */ +#define I2S_AISTR_ITST_SHIFT 16 +#define I2S_AISTR_ITR 0x00100000 /* input transfer request pending */ +#define I2S_AISTR_IUR 0x00200000 /* input FIFO underrun detected */ +#define I2S_AISTR_IOR 0x00400000 /* input FIFO overrun detected */ +#define I2S_AISTR_IDS 0x01000000 /* input DMA transfer size */ +#define I2S_AISTR_IDE 0x04000000 /* input DMA transfer request enable */ +#define I2S_AISTR_ITRIE 0x10000000 /* input transfer request interrupt enable */ +#define I2S_AISTR_IURIE 0x20000000 /* input FIFO underrun interrupt enable */ +#define I2S_AISTR_IORIE 0x40000000 /* input FIFO overrun interrupt enable */ +#define I2S_AISTR__IN_MASK 0x75700000 + +#define I2S_AICR_MI 0x00000001 /* mono input requested */ +#define I2S_AICR_AMI 0x00000002 /* relation between LRCKI/FS1 and SDI */ +#define I2S_AICR_LRI 0x00000004 /* function of LRCKI pin */ +#define I2S_AICR_SDMI 0x00000070 /* format of input audio data */ +#define I2S_AICR_SDMI_SHIFT 4 +#define I2S_AICR_CLI 0x00000080 /* input FIFO clearing control */ +#define I2S_AICR_IM 0x00000300 /* input state control */ +#define I2S_AICR_IM_SHIFT 8 +#define I2S_AICR__IN_MASK 0x000003f7 +#define I2S_AICR_MO 0x00001000 /* mono output requested */ +#define I2S_AICR_AMO 0x00002000 /* relation between LRCKO/FS0 and SDO */ +#define I2S_AICR_AMO_SHIFT 13 +#define I2S_AICR_LRO 0x00004000 /* function of LRCKO pin */ +#define I2S_AICR_SDMO 0x00070000 /* format of output audio data */ +#define I2S_AICR_SDMO_SHIFT 16 +#define I2S_AICR_CLO 0x00080000 /* output FIFO clearing control */ +#define I2S_AICR_OM 0x00100000 /* output state control */ +#define I2S_AICR__OUT_MASK 0x001f7000 +#define I2S_AICR_DIV 0x03000000 /* frequency division rate */ +#define I2S_AICR_DIV_SHIFT 24 +#define I2S_AICR_FL 0x20000000 /* frame length */ +#define I2S_AICR_FS 0x40000000 /* frame sync method */ +#define I2S_AICR_ME 0x80000000 /* master enable */ + +/* + * PCMCIA + */ +#define __addr_MB93493_PCMCIA(X) ((volatile unsigned long *)(__region_CS5 + (X))) + +/* + * GPIO + */ +#define __get_MB93493_GPIO_PDR(X) __get_MB93493(0x380 + (X) * 0xc0) +#define __set_MB93493_GPIO_PDR(X,V) __set_MB93493(0x380 + (X) * 0xc0, (V)) + +#define __get_MB93493_GPIO_GPDR(X) __get_MB93493(0x384 + (X) * 0xc0) +#define __set_MB93493_GPIO_GPDR(X,V) __set_MB93493(0x384 + (X) * 0xc0, (V)) + +#define __get_MB93493_GPIO_SIR(X) __get_MB93493(0x388 + (X) * 0xc0) +#define __set_MB93493_GPIO_SIR(X,V) __set_MB93493(0x388 + (X) * 0xc0, (V)) + +#define __get_MB93493_GPIO_SOR(X) __get_MB93493(0x38c + (X) * 0xc0) +#define __set_MB93493_GPIO_SOR(X,V) __set_MB93493(0x38c + (X) * 0xc0, (V)) + +#define __get_MB93493_GPIO_PDSR(X) __get_MB93493(0x390 + (X) * 0xc0) +#define __set_MB93493_GPIO_PDSR(X,V) __set_MB93493(0x390 + (X) * 0xc0, (V)) + +#define __get_MB93493_GPIO_PDCR(X) __get_MB93493(0x394 + (X) * 0xc0) +#define __set_MB93493_GPIO_PDCR(X,V) __set_MB93493(0x394 + (X) * 0xc0, (V)) + +#define __get_MB93493_GPIO_INTST(X) __get_MB93493(0x398 + (X) * 0xc0) +#define __set_MB93493_GPIO_INTST(X,V) __set_MB93493(0x398 + (X) * 0xc0, (V)) + +#define __get_MB93493_GPIO_IEHL(X) __get_MB93493(0x39c + (X) * 0xc0) +#define __set_MB93493_GPIO_IEHL(X,V) __set_MB93493(0x39c + (X) * 0xc0, (V)) + +#define __get_MB93493_GPIO_IELH(X) __get_MB93493(0x3a0 + (X) * 0xc0) +#define __set_MB93493_GPIO_IELH(X,V) __set_MB93493(0x3a0 + (X) * 0xc0, (V)) + +#endif /* _ASM_MB93493_REGS_H */ diff --git a/arch/frv/include/asm/mc146818rtc.h b/arch/frv/include/asm/mc146818rtc.h new file mode 100644 index 0000000..90dfb7a --- /dev/null +++ b/arch/frv/include/asm/mc146818rtc.h @@ -0,0 +1,16 @@ +/* mc146818rtc.h: RTC defs + * + * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + + +#endif /* _ASM_MC146818RTC_H */ diff --git a/arch/frv/include/asm/mem-layout.h b/arch/frv/include/asm/mem-layout.h new file mode 100644 index 0000000..2947764 --- /dev/null +++ b/arch/frv/include/asm/mem-layout.h @@ -0,0 +1,86 @@ +/* mem-layout.h: memory layout + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MEM_LAYOUT_H +#define _ASM_MEM_LAYOUT_H + +#ifndef __ASSEMBLY__ +#define __UL(X) ((unsigned long) (X)) +#else +#define __UL(X) (X) +#endif + +/* + * PAGE_SHIFT determines the page size + */ +#define PAGE_SHIFT 14 + +#ifndef __ASSEMBLY__ +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#else +#define PAGE_SIZE (1 << PAGE_SHIFT) +#endif + +#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* + * the slab must be aligned such that load- and store-double instructions don't + * fault if used + */ +#define ARCH_KMALLOC_MINALIGN 8 +#define ARCH_SLAB_MINALIGN 8 + +/*****************************************************************************/ +/* + * virtual memory layout from kernel's point of view + */ +#define PAGE_OFFSET ((unsigned long) &__page_offset) + +#ifdef CONFIG_MMU + +/* see Documentation/frv/mmu-layout.txt */ +#define KERNEL_LOWMEM_START __UL(0xc0000000) +#define KERNEL_LOWMEM_END __UL(0xd0000000) +#define VMALLOC_START __UL(0xd0000000) +#define VMALLOC_END __UL(0xd8000000) +#define PKMAP_BASE __UL(0xd8000000) +#define PKMAP_END __UL(0xdc000000) +#define KMAP_ATOMIC_SECONDARY_FRAME __UL(0xdc000000) +#define KMAP_ATOMIC_PRIMARY_FRAME __UL(0xdd000000) + +#endif + +#define KERNEL_IO_START __UL(0xe0000000) + + +/*****************************************************************************/ +/* + * memory layout from userspace's point of view + */ +#define BRK_BASE __UL(2 * 1024 * 1024 + PAGE_SIZE) +#define STACK_TOP __UL(2 * 1024 * 1024) +#define STACK_TOP_MAX __UL(0xc0000000) + +/* userspace process size */ +#ifdef CONFIG_MMU +#define TASK_SIZE (PAGE_OFFSET) +#else +#define TASK_SIZE __UL(0xFFFFFFFFUL) +#endif + +/* base of area at which unspecified mmaps will start */ +#ifdef CONFIG_BINFMT_ELF_FDPIC +#define TASK_UNMAPPED_BASE __UL(16 * 1024 * 1024) +#else +#define TASK_UNMAPPED_BASE __UL(TASK_SIZE / 3) +#endif + +#endif /* _ASM_MEM_LAYOUT_H */ diff --git a/arch/frv/include/asm/mman.h b/arch/frv/include/asm/mman.h new file mode 100644 index 0000000..b4371e9 --- /dev/null +++ b/arch/frv/include/asm/mman.h @@ -0,0 +1,18 @@ +#ifndef __ASM_MMAN_H__ +#define __ASM_MMAN_H__ + +#include <asm-generic/mman.h> + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +#endif /* __ASM_MMAN_H__ */ + diff --git a/arch/frv/include/asm/mmu.h b/arch/frv/include/asm/mmu.h new file mode 100644 index 0000000..86ca0e8 --- /dev/null +++ b/arch/frv/include/asm/mmu.h @@ -0,0 +1,41 @@ +/* mmu.h: memory management context for FR-V with or without MMU support + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_MMU_H +#define _ASM_MMU_H + +typedef struct { +#ifdef CONFIG_MMU + struct list_head id_link; /* link in list of context ID owners */ + unsigned short id; /* MMU context ID */ + unsigned short id_busy; /* true if ID is in CXNR */ + unsigned long itlb_cached_pge; /* [SCR0] PGE cached for insn TLB handler */ + unsigned long itlb_ptd_mapping; /* [DAMR4] PTD mapping for itlb cached PGE */ + unsigned long dtlb_cached_pge; /* [SCR1] PGE cached for data TLB handler */ + unsigned long dtlb_ptd_mapping; /* [DAMR5] PTD mapping for dtlb cached PGE */ + +#else + unsigned long end_brk; + +#endif + +#ifdef CONFIG_BINFMT_ELF_FDPIC + unsigned long exec_fdpic_loadmap; + unsigned long interp_fdpic_loadmap; +#endif + +} mm_context_t; + +#ifdef CONFIG_MMU +extern int __nongpreldata cxn_pinned; +extern int cxn_pin_by_pid(pid_t pid); +#endif + +#endif /* _ASM_MMU_H */ diff --git a/arch/frv/include/asm/mmu_context.h b/arch/frv/include/asm/mmu_context.h new file mode 100644 index 0000000..c7daa39 --- /dev/null +++ b/arch/frv/include/asm/mmu_context.h @@ -0,0 +1,50 @@ +/* mmu_context.h: MMU context management routines + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MMU_CONTEXT_H +#define _ASM_MMU_CONTEXT_H + +#include <asm/setup.h> +#include <asm/page.h> +#include <asm/pgalloc.h> +#include <asm-generic/mm_hooks.h> + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +#ifdef CONFIG_MMU +extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm); +extern void change_mm_context(mm_context_t *old, mm_context_t *ctx, pgd_t *_pgd); +extern void destroy_context(struct mm_struct *mm); + +#else +#define init_new_context(tsk, mm) ({ 0; }) +#define change_mm_context(old, ctx, _pml4) do {} while(0) +#define destroy_context(mm) do {} while(0) +#endif + +#define switch_mm(prev, next, tsk) \ +do { \ + if (prev != next) \ + change_mm_context(&prev->context, &next->context, next->pgd); \ +} while(0) + +#define activate_mm(prev, next) \ +do { \ + change_mm_context(&prev->context, &next->context, next->pgd); \ +} while(0) + +#define deactivate_mm(tsk, mm) \ +do { \ +} while(0) + +#endif diff --git a/arch/frv/include/asm/module.h b/arch/frv/include/asm/module.h new file mode 100644 index 0000000..3d5c636 --- /dev/null +++ b/arch/frv/include/asm/module.h @@ -0,0 +1,28 @@ +/* module.h: FRV module stuff + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_MODULE_H +#define _ASM_MODULE_H + +struct mod_arch_specific +{ +}; + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr + +/* + * Include the architecture version. + */ +#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " " + +#endif /* _ASM_MODULE_H */ + diff --git a/arch/frv/include/asm/msgbuf.h b/arch/frv/include/asm/msgbuf.h new file mode 100644 index 0000000..97ceb55 --- /dev/null +++ b/arch/frv/include/asm/msgbuf.h @@ -0,0 +1,32 @@ +#ifndef _ASM_MSGBUF_H +#define _ASM_MSGBUF_H + +/* + * The msqid64_ds structure for FR-V architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _ASM_MSGBUF_H */ + diff --git a/arch/frv/include/asm/mutex.h b/arch/frv/include/asm/mutex.h new file mode 100644 index 0000000..458c1f7 --- /dev/null +++ b/arch/frv/include/asm/mutex.h @@ -0,0 +1,9 @@ +/* + * Pull in the generic implementation for the mutex fastpath. + * + * TODO: implement optimized primitives instead, or leave the generic + * implementation in place, or pick the atomic_xchg() based generic + * implementation. (see asm-generic/mutex-xchg.h for details) + */ + +#include <asm-generic/mutex-dec.h> diff --git a/arch/frv/include/asm/page.h b/arch/frv/include/asm/page.h new file mode 100644 index 0000000..bd9c220 --- /dev/null +++ b/arch/frv/include/asm/page.h @@ -0,0 +1,78 @@ +#ifndef _ASM_PAGE_H +#define _ASM_PAGE_H + +#include <asm/virtconvert.h> +#include <asm/mem-layout.h> +#include <asm/sections.h> +#include <asm/setup.h> + +#ifndef __ASSEMBLY__ + +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) + +#define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE) +#define copy_user_page(vto, vfrom, vaddr, topg) memcpy((vto), (vfrom), PAGE_SIZE) + +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long ste[64];} pmd_t; +typedef struct { pmd_t pue[1]; } pud_t; +typedef struct { pud_t pge[1]; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).ste[0]) +#define pud_val(x) ((x).pue[0]) +#define pgd_val(x) ((x).pge[0]) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pud(x) ((pud_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) +#define PTE_MASK PAGE_MASK + +#define devmem_is_allowed(pfn) 1 + +#define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr)) +#define __va(paddr) phys_to_virt((unsigned long) (paddr)) + +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) + +extern unsigned long max_low_pfn; +extern unsigned long min_low_pfn; +extern unsigned long max_pfn; + +#ifdef CONFIG_MMU +#define pfn_valid(pfn) ((pfn) < max_mapnr) +#else +#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) +#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_low_pfn) + +#endif + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + + +#ifdef CONFIG_MMU +#define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#endif + +#endif /* __ASSEMBLY__ */ + +#include <asm-generic/memory_model.h> +#include <asm-generic/page.h> + +#endif /* _ASM_PAGE_H */ diff --git a/arch/frv/include/asm/param.h b/arch/frv/include/asm/param.h new file mode 100644 index 0000000..6859dd5 --- /dev/null +++ b/arch/frv/include/asm/param.h @@ -0,0 +1,22 @@ +#ifndef _ASM_PARAM_H +#define _ASM_PARAM_H + +#ifdef __KERNEL__ +#define HZ CONFIG_HZ /* Internal kernel timer frequency */ +#define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +#define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 16384 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _ASM_PARAM_H */ diff --git a/arch/frv/include/asm/pci.h b/arch/frv/include/asm/pci.h new file mode 100644 index 0000000..585d9b4 --- /dev/null +++ b/arch/frv/include/asm/pci.h @@ -0,0 +1,118 @@ +/* pci.h: FR-V specific PCI declarations + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from include/asm-m68k/pci.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef ASM_PCI_H +#define ASM_PCI_H + +#include <linux/mm.h> +#include <asm/scatterlist.h> +#include <asm-generic/pci-dma-compat.h> +#include <asm-generic/pci.h> + +struct pci_dev; + +#define pcibios_assign_all_busses() 0 + +extern void pcibios_set_master(struct pci_dev *dev); + +extern void pcibios_penalize_isa_irq(int irq); + +#ifdef CONFIG_MMU +extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle); +extern void consistent_free(void *vaddr); +extern void consistent_sync(void *vaddr, size_t size, int direction); +extern void consistent_sync_page(struct page *page, unsigned long offset, + size_t size, int direction); +#endif + +extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle); + +extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +/* Return the index of the PCI controller for device PDEV. */ +#define pci_controller_num(PDEV) (0) + +/* The PCI address space does equal the physical memory + * address space. The networking and block device layers use + * this boolean for bounce buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +/* pci_unmap_{page,single} is a nop so... */ +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) +#define pci_unmap_addr(PTR, ADDR_NAME) (0) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) +#define pci_unmap_len(PTR, LEN_NAME) (0) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) + +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + +/* + * These are pretty much arbitary with the CoMEM implementation. + * We have the whole address space to ourselves. + */ +#define PCIBIOS_MIN_IO 0x100 +#define PCIBIOS_MIN_MEM 0x00010000 + +/* Make physical memory consistent for a single + * streaming mode DMA translation after a transfer. + * + * If you perform a pci_map_single() but wish to interrogate the + * buffer using the cpu, yet do not wish to teardown the PCI dma + * mapping, you must call this function before doing so. At the + * next point you give the PCI dma address back to the card, the + * device again owns the buffer. + */ +static inline void pci_dma_sync_single(struct pci_dev *hwdev, + dma_addr_t dma_handle, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), + (unsigned long)bus_to_virt(dma_handle) + size); +} + +/* Make physical memory consistent for a set of streaming + * mode DMA translations after a transfer. + * + * The same as pci_dma_sync_single but for a scatter-gather list, + * same rules and usage. + */ +static inline void pci_dma_sync_sg(struct pci_dev *hwdev, + struct scatterlist *sg, + int nelems, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + BUG(); + + for (i = 0; i < nelems; i++) + frv_cache_wback_inv(sg_dma_address(&sg[i]), + sg_dma_address(&sg[i])+sg_dma_len(&sg[i])); +} + + +#endif diff --git a/arch/frv/include/asm/percpu.h b/arch/frv/include/asm/percpu.h new file mode 100644 index 0000000..2cad3f8 --- /dev/null +++ b/arch/frv/include/asm/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ASM_PERCPU_H +#define __ASM_PERCPU_H + +#include <asm-generic/percpu.h> + +#endif /* __ASM_PERCPU_H */ diff --git a/arch/frv/include/asm/pgalloc.h b/arch/frv/include/asm/pgalloc.h new file mode 100644 index 0000000..971e6ad --- /dev/null +++ b/arch/frv/include/asm/pgalloc.h @@ -0,0 +1,69 @@ +/* pgalloc.h: Page allocation routines for FRV + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Derived from: + * include/asm-m68knommu/pgalloc.h + * include/asm-i386/pgalloc.h + */ +#ifndef _ASM_PGALLOC_H +#define _ASM_PGALLOC_H + +#include <asm/setup.h> +#include <asm/virtconvert.h> + +#ifdef CONFIG_MMU + +#define pmd_populate_kernel(mm, pmd, pte) __set_pmd(pmd, __pa(pte) | _PAGE_TABLE) +#define pmd_populate(MM, PMD, PAGE) \ +do { \ + __set_pmd((PMD), page_to_pfn(PAGE) << PAGE_SHIFT | _PAGE_TABLE); \ +} while(0) +#define pmd_pgtable(pmd) pmd_page(pmd) + +/* + * Allocate and free page tables. + */ + +extern pgd_t *pgd_alloc(struct mm_struct *); +extern void pgd_free(struct mm_struct *mm, pgd_t *); + +extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); + +extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long); + +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + free_page((unsigned long)pte); +} + +static inline void pte_free(struct mm_struct *mm, pgtable_t pte) +{ + pgtable_page_dtor(pte); + __free_page(pte); +} + +#define __pte_free_tlb(tlb,pte) \ +do { \ + pgtable_page_dtor(pte); \ + tlb_remove_page((tlb),(pte)); \ +} while (0) + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + * (In the PAE case we free the pmds as part of the pgd.) + */ +#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *) 2); }) +#define pmd_free(mm, x) do { } while (0) +#define __pmd_free_tlb(tlb,x) do { } while (0) + +#endif /* CONFIG_MMU */ + +#endif /* _ASM_PGALLOC_H */ diff --git a/arch/frv/include/asm/pgtable.h b/arch/frv/include/asm/pgtable.h new file mode 100644 index 0000000..3323301 --- /dev/null +++ b/arch/frv/include/asm/pgtable.h @@ -0,0 +1,549 @@ +/* pgtable.h: FR-V page table mangling + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Derived from: + * include/asm-m68knommu/pgtable.h + * include/asm-i386/pgtable.h + */ + +#ifndef _ASM_PGTABLE_H +#define _ASM_PGTABLE_H + +#include <asm/mem-layout.h> +#include <asm/setup.h> +#include <asm/processor.h> + +#ifndef __ASSEMBLY__ +#include <linux/threads.h> +#include <linux/slab.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/sched.h> +struct vm_area_struct; +#endif + +#ifndef __ASSEMBLY__ +#if defined(CONFIG_HIGHPTE) +typedef unsigned long pte_addr_t; +#else +typedef pte_t *pte_addr_t; +#endif +#endif + +/*****************************************************************************/ +/* + * MMU-less operation case first + */ +#ifndef CONFIG_MMU + +#define pgd_present(pgd) (1) /* pages are always present on NO_MM */ +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_clear(pgdp) +#define kern_addr_valid(addr) (1) +#define pmd_offset(a, b) ((void *) 0) + +#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */ +#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */ + +#define __swp_type(x) (0) +#define __swp_offset(x) (0) +#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +#ifndef __ASSEMBLY__ +static inline int pte_file(pte_t pte) { return 0; } +#endif + +#define ZERO_PAGE(vaddr) ({ BUG(); NULL; }) + +#define swapper_pg_dir ((pgd_t *) NULL) + +#define pgtable_cache_init() do {} while (0) + +#include <asm-generic/pgtable.h> + +#else /* !CONFIG_MMU */ +/*****************************************************************************/ +/* + * then MMU operation + */ + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#ifndef __ASSEMBLY__ +extern unsigned long empty_zero_page; +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) +#endif + +/* + * we use 2-level page tables, folding the PMD (mid-level table) into the PGE (top-level entry) + * [see Documentation/frv/mmu-layout.txt] + * + * Page Directory: + * - Size: 16KB + * - 64 PGEs per PGD + * - Each PGE holds 1 PUD and covers 64MB + * + * Page Upper Directory: + * - Size: 256B + * - 1 PUE per PUD + * - Each PUE holds 1 PMD and covers 64MB + * + * Page Mid-Level Directory + * - Size: 256B + * - 1 PME per PMD + * - Each PME holds 64 STEs, all of which point to separate chunks of the same Page Table + * - All STEs are instantiated at the same time + * + * Page Table + * - Size: 16KB + * - 4096 PTEs per PT + * - Each Linux PT is subdivided into 64 FR451 PT's, each of which holds 64 entries + * + * Pages + * - Size: 4KB + * + * total PTEs + * = 1 PML4E * 64 PGEs * 1 PUEs * 1 PMEs * 4096 PTEs + * = 1 PML4E * 64 PGEs * 64 STEs * 64 PTEs/FR451-PT + * = 262144 (or 256 * 1024) + */ +#define PGDIR_SHIFT 26 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE - 1)) +#define PTRS_PER_PGD 64 + +#define PUD_SHIFT 26 +#define PTRS_PER_PUD 1 +#define PUD_SIZE (1UL << PUD_SHIFT) +#define PUD_MASK (~(PUD_SIZE - 1)) +#define PUE_SIZE 256 + +#define PMD_SHIFT 26 +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE - 1)) +#define PTRS_PER_PMD 1 +#define PME_SIZE 256 + +#define __frv_PT_SIZE 256 + +#define PTRS_PER_PTE 4096 + +#define USER_PGDS_IN_LAST_PML4 (TASK_SIZE / PGDIR_SIZE) +#define FIRST_USER_ADDRESS 0 + +#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) +#define KERNEL_PGD_PTRS (PTRS_PER_PGD - USER_PGD_PTRS) + +#define TWOLEVEL_PGDIR_SHIFT 26 +#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT) +#define BOOT_KERNEL_PGD_PTRS (PTRS_PER_PGD - BOOT_USER_PGD_PTRS) + +#ifndef __ASSEMBLY__ + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pud_ERROR(e) \ + printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(e))) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(pgd_val(e)))) + +/* + * Certain architectures need to do special things when PTEs + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) \ +do { \ + *(pteptr) = (pteval); \ + asm volatile("dcf %M0" :: "U"(*pteptr)); \ +} while(0) +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + +/* + * pgd_offset() returns a (pgd_t *) + * pgd_index() is used get the offset into the pgd page's array of pgd_t's; + */ +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) + +/* + * a shortcut which implies the use of the kernel's pgd, instead + * of a process's + */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pud is never bad, and a pud always exists (as it's folded + * into the pgd entry) + */ +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } +static inline void pgd_clear(pgd_t *pgd) { } + +#define pgd_populate(mm, pgd, pud) do { } while (0) +/* + * (puds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pgd(pgdptr, pgdval) \ +do { \ + memcpy((pgdptr), &(pgdval), sizeof(pgd_t)); \ + asm volatile("dcf %M0" :: "U"(*(pgdptr))); \ +} while(0) + +static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) +{ + return (pud_t *) pgd; +} + +#define pgd_page(pgd) (pud_page((pud_t){ pgd })) +#define pgd_page_vaddr(pgd) (pud_page_vaddr((pud_t){ pgd })) + +/* + * allocating and freeing a pud is trivial: the 1-entry pud is + * inside the pgd, so has no extra memory associated with it. + */ +#define pud_alloc_one(mm, address) NULL +#define pud_free(mm, x) do { } while (0) +#define __pud_free_tlb(tlb, x) do { } while (0) + +/* + * The "pud_xxx()" functions here are trivial for a folded two-level + * setup: the pmd is never bad, and a pmd always exists (as it's folded + * into the pud entry) + */ +static inline int pud_none(pud_t pud) { return 0; } +static inline int pud_bad(pud_t pud) { return 0; } +static inline int pud_present(pud_t pud) { return 1; } +static inline void pud_clear(pud_t *pud) { } + +#define pud_populate(mm, pmd, pte) do { } while (0) + +/* + * (pmds are folded into puds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pud(pudptr, pudval) set_pmd((pmd_t *)(pudptr), (pmd_t) { pudval }) + +#define pud_page(pud) (pmd_page((pmd_t){ pud })) +#define pud_page_vaddr(pud) (pmd_page_vaddr((pmd_t){ pud })) + +/* + * (pmds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +extern void __set_pmd(pmd_t *pmdptr, unsigned long __pmd); + +#define set_pmd(pmdptr, pmdval) \ +do { \ + __set_pmd((pmdptr), (pmdval).ste[0]); \ +} while(0) + +#define __pmd_index(address) 0 + +static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address) +{ + return (pmd_t *) dir + __pmd_index(address); +} + +#define pte_same(a, b) ((a).pte == (b).pte) +#define pte_page(x) (mem_map + ((unsigned long)(((x).pte >> PAGE_SHIFT)))) +#define pte_none(x) (!(x).pte) +#define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT))) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#define VMALLOC_VMADDR(x) ((unsigned long) (x)) + +#endif /* !__ASSEMBLY__ */ + +/* + * control flags in AMPR registers and TLB entries + */ +#define _PAGE_BIT_PRESENT xAMPRx_V_BIT +#define _PAGE_BIT_WP DAMPRx_WP_BIT +#define _PAGE_BIT_NOCACHE xAMPRx_C_BIT +#define _PAGE_BIT_SUPER xAMPRx_S_BIT +#define _PAGE_BIT_ACCESSED xAMPRx_RESERVED8_BIT +#define _PAGE_BIT_DIRTY xAMPRx_M_BIT +#define _PAGE_BIT_NOTGLOBAL xAMPRx_NG_BIT + +#define _PAGE_PRESENT xAMPRx_V +#define _PAGE_WP DAMPRx_WP +#define _PAGE_NOCACHE xAMPRx_C +#define _PAGE_SUPER xAMPRx_S +#define _PAGE_ACCESSED xAMPRx_RESERVED8 /* accessed if set */ +#define _PAGE_DIRTY xAMPRx_M +#define _PAGE_NOTGLOBAL xAMPRx_NG + +#define _PAGE_RESERVED_MASK (xAMPRx_RESERVED8 | xAMPRx_RESERVED13) + +#define _PAGE_FILE 0x002 /* set:pagecache unset:swap */ +#define _PAGE_PROTNONE 0x000 /* If not present */ + +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define __PGPROT_BASE \ + (_PAGE_PRESENT | xAMPRx_SS_16Kb | xAMPRx_D | _PAGE_NOTGLOBAL | _PAGE_ACCESSED) + +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(__PGPROT_BASE) +#define PAGE_COPY __pgprot(__PGPROT_BASE | _PAGE_WP) +#define PAGE_READONLY __pgprot(__PGPROT_BASE | _PAGE_WP) + +#define __PAGE_KERNEL (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY) +#define __PAGE_KERNEL_NOCACHE (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_NOCACHE) +#define __PAGE_KERNEL_RO (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_WP) + +#define MAKE_GLOBAL(x) __pgprot((x) & ~_PAGE_NOTGLOBAL) + +#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL) +#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) + +#define _PAGE_TABLE (_PAGE_PRESENT | xAMPRx_SS_16Kb) + +#ifndef __ASSEMBLY__ + +/* + * The FR451 can do execute protection by virtue of having separate TLB miss handlers for + * instruction access and for data access. However, we don't have enough reserved bits to say + * "execute only", so we don't bother. If you can read it, you can execute it and vice versa. + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +/* + * Define this to warn about kernel memory accesses that are + * done without a 'access_ok(VERIFY_WRITE,..)' + */ +#undef TEST_ACCESS_OK + +#define pte_present(x) (pte_val(x) & _PAGE_PRESENT) +#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) + +#define pmd_none(x) (!pmd_val(x)) +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) +#define pmd_bad(x) (pmd_val(x) & xAMPRx_SS) +#define pmd_clear(xp) do { __set_pmd(xp, 0); } while(0) + +#define pmd_page_vaddr(pmd) \ + ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) + +#ifndef CONFIG_DISCONTIGMEM +#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) +#endif + +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_dirty(pte_t pte) { return (pte).pte & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return (pte).pte & _PAGE_ACCESSED; } +static inline int pte_write(pte_t pte) { return !((pte).pte & _PAGE_WP); } +static inline int pte_special(pte_t pte) { return 0; } + +static inline pte_t pte_mkclean(pte_t pte) { (pte).pte &= ~_PAGE_DIRTY; return pte; } +static inline pte_t pte_mkold(pte_t pte) { (pte).pte &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte |= _PAGE_WP; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte &= ~_PAGE_WP; return pte; } +static inline pte_t pte_mkspecial(pte_t pte) { return pte; } + +static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) +{ + int i = test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep); + asm volatile("dcf %M0" :: "U"(*ptep)); + return i; +} + +static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + unsigned long x = xchg(&ptep->pte, 0); + asm volatile("dcf %M0" :: "U"(*ptep)); + return __pte(x); +} + +static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + set_bit(_PAGE_BIT_WP, ptep); + asm volatile("dcf %M0" :: "U"(*ptep)); +} + +/* + * Macro to mark a page protection value as "uncacheable" + */ +#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE)) + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ + +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) +#define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE) + +/* This takes a physical page address that is used by the remapping functions */ +#define mk_pte_phys(physpage, pgprot) pfn_pte((physpage) >> PAGE_SHIFT, pgprot) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte.pte &= _PAGE_CHG_MASK; + pte.pte |= pgprot_val(newprot); + return pte; +} + +/* to find an entry in a page-table-directory. */ +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) +#define pgd_index_k(addr) pgd_index(addr) + +/* Find an entry in the bottom-level page table.. */ +#define __pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + +/* + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE] + * + * this macro returns the index of the entry in the pte page which would + * control the given virtual address + */ +#define pte_index(address) \ + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address)) + +#if defined(CONFIG_HIGHPTE) +#define pte_offset_map(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) +#define pte_offset_map_nested(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address)) +#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) +#define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1) +#else +#define pte_offset_map(dir, address) \ + ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address)) +#define pte_offset_map_nested(dir, address) pte_offset_map((dir), (address)) +#define pte_unmap(pte) do { } while (0) +#define pte_unmap_nested(pte) do { } while (0) +#endif + +/* + * Handle swap and file entries + * - the PTE is encoded in the following format: + * bit 0: Must be 0 (!_PAGE_PRESENT) + * bit 1: Type: 0 for swap, 1 for file (_PAGE_FILE) + * bits 2-7: Swap type + * bits 8-31: Swap offset + * bits 2-31: File pgoff + */ +#define __swp_type(x) (((x).val >> 2) & 0x1f) +#define __swp_offset(x) ((x).val >> 8) +#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) }) +#define __pte_to_swp_entry(_pte) ((swp_entry_t) { (_pte).pte }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +static inline int pte_file(pte_t pte) +{ + return pte.pte & _PAGE_FILE; +} + +#define PTE_FILE_MAX_BITS 29 + +#define pte_to_pgoff(PTE) ((PTE).pte >> 2) +#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE) + +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +#define PageSkip(page) (0) +#define kern_addr_valid(addr) (1) + +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +#define __HAVE_ARCH_PTEP_SET_WRPROTECT +#define __HAVE_ARCH_PTE_SAME +#include <asm-generic/pgtable.h> + +/* + * preload information about a newly instantiated PTE into the SCR0/SCR1 PGE cache + */ +static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ + struct mm_struct *mm; + unsigned long ampr; + + mm = current->mm; + if (mm) { + pgd_t *pge = pgd_offset(mm, address); + pud_t *pue = pud_offset(pge, address); + pmd_t *pme = pmd_offset(pue, address); + + ampr = pme->ste[0] & 0xffffff00; + ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C | + xAMPRx_V; + } else { + address = ULONG_MAX; + ampr = 0; + } + + asm volatile("movgs %0,scr0\n" + "movgs %0,scr1\n" + "movgs %1,dampr4\n" + "movgs %1,dampr5\n" + : + : "r"(address), "r"(ampr) + ); +} + +#ifdef CONFIG_PROC_FS +extern char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer); +#endif + +extern void __init pgtable_cache_init(void); + +#endif /* !__ASSEMBLY__ */ +#endif /* !CONFIG_MMU */ + +#ifndef __ASSEMBLY__ +extern void __init paging_init(void); +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_PGTABLE_H */ diff --git a/arch/frv/include/asm/poll.h b/arch/frv/include/asm/poll.h new file mode 100644 index 0000000..0d01479 --- /dev/null +++ b/arch/frv/include/asm/poll.h @@ -0,0 +1,12 @@ +#ifndef _ASM_POLL_H +#define _ASM_POLL_H + +#define POLLWRNORM POLLOUT +#define POLLWRBAND 256 + +#include <asm-generic/poll.h> + +#undef POLLREMOVE + +#endif + diff --git a/arch/frv/include/asm/posix_types.h b/arch/frv/include/asm/posix_types.h new file mode 100644 index 0000000..a9f1f5b --- /dev/null +++ b/arch/frv/include/asm/posix_types.h @@ -0,0 +1,62 @@ +#ifndef _ASM_POSIX_TYPES_H +#define _ASM_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#if defined(__KERNEL__) + +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) + +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) + +#undef __FD_ISSET +#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d))) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif /* defined(__KERNEL__) */ + +#endif + diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h new file mode 100644 index 0000000..3744f2e --- /dev/null +++ b/arch/frv/include/asm/processor.h @@ -0,0 +1,153 @@ +/* processor.h: FRV processor definitions + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_PROCESSOR_H +#define _ASM_PROCESSOR_H + +#include <asm/mem-layout.h> + +#ifndef __ASSEMBLY__ +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#include <linux/compiler.h> +#include <linux/linkage.h> +#include <asm/sections.h> +#include <asm/segment.h> +#include <asm/fpu.h> +#include <asm/registers.h> +#include <asm/ptrace.h> +#include <asm/current.h> +#include <asm/cache.h> + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* + * CPU type and hardware bug flags. Kept separately for each CPU. + */ +struct cpuinfo_frv { +#ifdef CONFIG_MMU + unsigned long *pgd_quick; + unsigned long *pte_quick; + unsigned long pgtable_cache_sz; +#endif +} __cacheline_aligned; + +extern struct cpuinfo_frv __nongprelbss boot_cpu_data; + +#define cpu_data (&boot_cpu_data) +#define current_cpu_data boot_cpu_data + +/* + * Bus types + */ +#define EISA_bus 0 +#define MCA_bus 0 + +struct thread_struct { + struct pt_regs *frame; /* [GR28] exception frame ptr for this thread */ + struct task_struct *curr; /* [GR29] current pointer for this thread */ + unsigned long sp; /* [GR1 ] kernel stack pointer */ + unsigned long fp; /* [GR2 ] kernel frame pointer */ + unsigned long lr; /* link register */ + unsigned long pc; /* program counter */ + unsigned long gr[12]; /* [GR16-GR27] */ + unsigned long sched_lr; /* LR from schedule() */ + + union { + struct pt_regs *frame0; /* top (user) stack frame */ + struct user_context *user; /* userspace context */ + }; +} __attribute__((aligned(8))); + +extern struct pt_regs *__kernel_frame0_ptr; +extern struct task_struct *__kernel_current_task; + +#endif + +#ifndef __ASSEMBLY__ +#define INIT_THREAD_FRAME0 \ + ((struct pt_regs *) \ + (sizeof(init_stack) + (unsigned long) init_stack - sizeof(struct user_context))) + +#define INIT_THREAD { \ + NULL, \ + (struct task_struct *) init_stack, \ + 0, 0, 0, 0, \ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \ + 0, \ + { INIT_THREAD_FRAME0 }, \ +} + +/* + * do necessary setup to start up a newly executed thread. + * - need to discard the frame stacked by init() invoking the execve syscall + */ +#define start_thread(_regs, _pc, _usp) \ +do { \ + set_fs(USER_DS); /* reads from user space */ \ + __frame = __kernel_frame0_ptr; \ + __frame->pc = (_pc); \ + __frame->psr &= ~PSR_S; \ + __frame->sp = (_usp); \ +} while(0) + +extern void prepare_to_copy(struct task_struct *tsk); + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); +extern asmlinkage void save_user_regs(struct user_context *target); +extern asmlinkage void *restore_user_regs(const struct user_context *target, ...); + +#define copy_segments(tsk, mm) do { } while (0) +#define release_segments(mm) do { } while (0) +#define forget_segments() do { } while (0) + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +/* + * Return saved PC of a blocked thread. + */ +extern unsigned long thread_saved_pc(struct task_struct *tsk); + +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) +#define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp) + +/* Allocation and freeing of basic task resources. */ +extern struct task_struct *alloc_task_struct(void); +extern void free_task_struct(struct task_struct *p); + +#define cpu_relax() barrier() + +/* data cache prefetch */ +#define ARCH_HAS_PREFETCH +static inline void prefetch(const void *x) +{ + asm volatile("dcpl %0,gr0,#0" : : "r"(x)); +} + +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_PROCESSOR_H */ diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h new file mode 100644 index 0000000..cf69340 --- /dev/null +++ b/arch/frv/include/asm/ptrace.h @@ -0,0 +1,83 @@ +/* ptrace.h: ptrace() relevant definitions + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_PTRACE_H +#define _ASM_PTRACE_H + +#include <asm/registers.h> +#ifdef __KERNEL__ +#include <asm/irq_regs.h> + +#define in_syscall(regs) (((regs)->tbr & TBR_TT) == TBR_TT_TRAP0) +#endif + + +#define PT_PSR 0 +#define PT_ISR 1 +#define PT_CCR 2 +#define PT_CCCR 3 +#define PT_LR 4 +#define PT_LCR 5 +#define PT_PC 6 + +#define PT__STATUS 7 /* exception status */ +#define PT_SYSCALLNO 8 /* syscall number or -1 */ +#define PT_ORIG_GR8 9 /* saved GR8 for signal handling */ +#define PT_GNER0 10 +#define PT_GNER1 11 +#define PT_IACC0H 12 +#define PT_IACC0L 13 + +#define PT_GR(j) ( 14 + (j)) /* GRj for 0<=j<=63 */ +#define PT_FR(j) ( 78 + (j)) /* FRj for 0<=j<=63 */ +#define PT_FNER(j) (142 + (j)) /* FNERj for 0<=j<=1 */ +#define PT_MSR(j) (144 + (j)) /* MSRj for 0<=j<=2 */ +#define PT_ACC(j) (146 + (j)) /* ACCj for 0<=j<=7 */ +#define PT_ACCG(jklm) (154 + (jklm)) /* ACCGjklm for 0<=jklm<=1 (reads four regs per slot) */ +#define PT_FSR(j) (156 + (j)) /* FSRj for 0<=j<=0 */ +#define PT__GPEND 78 +#define PT__END 157 + +#define PT_TBR PT_GR(0) +#define PT_SP PT_GR(1) +#define PT_FP PT_GR(2) +#define PT_PREV_FRAME PT_GR(28) /* previous exception frame pointer (old gr28 value) */ +#define PT_CURR_TASK PT_GR(29) /* current task */ + + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */ + +#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */ +#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */ + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +/* + * we dedicate GR28 to keeping a pointer to the current exception frame + * - gr28 is destroyed on entry to the kernel from userspace + */ +register struct pt_regs *__frame asm("gr28"); + +#define user_mode(regs) (!((regs)->psr & PSR_S)) +#define instruction_pointer(regs) ((regs)->pc) + +extern unsigned long user_stack(const struct pt_regs *); +extern void show_regs(struct pt_regs *); +#define profile_pc(regs) ((regs)->pc) +#endif + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_PTRACE_H */ diff --git a/arch/frv/include/asm/registers.h b/arch/frv/include/asm/registers.h new file mode 100644 index 0000000..9666119 --- /dev/null +++ b/arch/frv/include/asm/registers.h @@ -0,0 +1,232 @@ +/* registers.h: register frame declarations + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/* + * notes: + * + * (1) that the members of all these structures are carefully aligned to permit + * usage of STD/STDF instructions + * + * (2) if you change these structures, you must change the code in + * arch/frvnommu/kernel/{break.S,entry.S,switch_to.S,gdb-stub.c} + * + * + * the kernel stack space block looks like this: + * + * +0x2000 +---------------------- + * | union { + * | struct frv_frame0 { + * | struct user_context { + * | struct user_int_regs + * | struct user_fpmedia_regs + * | } + * | struct frv_debug_regs + * | } + * | struct pt_regs [user exception] + * | } + * +---------------------- <-- __kernel_frame0_ptr (maybe GR28) + * | + * | kernel stack + * | + * |...................... + * | struct pt_regs [kernel exception] + * |...................... <-- __kernel_frame0_ptr (maybe GR28) + * | + * | kernel stack + * | + * |...................... <-- stack pointer (GR1) + * | + * | unused stack space + * | + * +---------------------- + * | struct thread_info + * +0x0000 +---------------------- <-- __current_thread_info (GR15); + * + * note that GR28 points to the current exception frame + */ + +#ifndef _ASM_REGISTERS_H +#define _ASM_REGISTERS_H + +#ifndef __ASSEMBLY__ +#define __OFFSET(X,N) ((X)+(N)*4) +#define __OFFSETC(X,N) xxxxxxxxxxxxxxxxxxxxxxxx +#else +#define __OFFSET(X,N) ((X)+(N)*4) +#define __OFFSETC(X,N) ((X)+(N)) +#endif + +/*****************************************************************************/ +/* + * Exception/Interrupt frame + * - held on kernel stack + * - 8-byte aligned on stack (old SP is saved in frame) + * - GR0 is fixed 0, so we don't save it + */ +#ifndef __ASSEMBLY__ + +struct pt_regs { + unsigned long psr; /* Processor Status Register */ + unsigned long isr; /* Integer Status Register */ + unsigned long ccr; /* Condition Code Register */ + unsigned long cccr; /* Condition Code for Conditional Insns Register */ + unsigned long lr; /* Link Register */ + unsigned long lcr; /* Loop Count Register */ + unsigned long pc; /* Program Counter Register */ + unsigned long __status; /* exception status */ + unsigned long syscallno; /* syscall number or -1 */ + unsigned long orig_gr8; /* original syscall arg #1 */ + unsigned long gner0; + unsigned long gner1; + unsigned long long iacc0; + unsigned long tbr; /* GR0 is fixed zero, so we use this for TBR */ + unsigned long sp; /* GR1: USP/KSP */ + unsigned long fp; /* GR2: FP */ + unsigned long gr3; + unsigned long gr4; + unsigned long gr5; + unsigned long gr6; + unsigned long gr7; /* syscall number */ + unsigned long gr8; /* 1st syscall param; syscall return */ + unsigned long gr9; /* 2nd syscall param */ + unsigned long gr10; /* 3rd syscall param */ + unsigned long gr11; /* 4th syscall param */ + unsigned long gr12; /* 5th syscall param */ + unsigned long gr13; /* 6th syscall param */ + unsigned long gr14; + unsigned long gr15; + unsigned long gr16; /* GP pointer */ + unsigned long gr17; /* small data */ + unsigned long gr18; /* PIC/PID */ + unsigned long gr19; + unsigned long gr20; + unsigned long gr21; + unsigned long gr22; + unsigned long gr23; + unsigned long gr24; + unsigned long gr25; + unsigned long gr26; + unsigned long gr27; + struct pt_regs *next_frame; /* GR28 - next exception frame */ + unsigned long gr29; /* GR29 - OS reserved */ + unsigned long gr30; /* GR30 - OS reserved */ + unsigned long gr31; /* GR31 - OS reserved */ +} __attribute__((aligned(8))); + +#endif + +#define REG__STATUS_STEP 0x00000001 /* - reenable single stepping on return */ +#define REG__STATUS_STEPPED 0x00000002 /* - single step caused exception */ +#define REG__STATUS_BROKE 0x00000004 /* - BREAK insn caused exception */ +#define REG__STATUS_SYSC_ENTRY 0x40000000 /* - T on syscall entry (ptrace.c only) */ +#define REG__STATUS_SYSC_EXIT 0x80000000 /* - T on syscall exit (ptrace.c only) */ + +#define REG_GR(R) __OFFSET(REG_GR0, (R)) + +#define REG_SP REG_GR(1) +#define REG_FP REG_GR(2) +#define REG_PREV_FRAME REG_GR(28) /* previous exception frame pointer (old gr28 value) */ +#define REG_CURR_TASK REG_GR(29) /* current task */ + +/*****************************************************************************/ +/* + * debugging registers + */ +#ifndef __ASSEMBLY__ + +struct frv_debug_regs +{ + unsigned long dcr; + unsigned long ibar[4] __attribute__((aligned(8))); + unsigned long dbar[4] __attribute__((aligned(8))); + unsigned long dbdr[4][4] __attribute__((aligned(8))); + unsigned long dbmr[4][4] __attribute__((aligned(8))); +} __attribute__((aligned(8))); + +#endif + +/*****************************************************************************/ +/* + * userspace registers + */ +#ifndef __ASSEMBLY__ + +struct user_int_regs +{ + /* integer registers + * - up to gr[31] mirror pt_regs + * - total size must be multiple of 8 bytes + */ + unsigned long psr; /* Processor Status Register */ + unsigned long isr; /* Integer Status Register */ + unsigned long ccr; /* Condition Code Register */ + unsigned long cccr; /* Condition Code for Conditional Insns Register */ + unsigned long lr; /* Link Register */ + unsigned long lcr; /* Loop Count Register */ + unsigned long pc; /* Program Counter Register */ + unsigned long __status; /* exception status */ + unsigned long syscallno; /* syscall number or -1 */ + unsigned long orig_gr8; /* original syscall arg #1 */ + unsigned long gner[2]; + unsigned long long iacc[1]; + + union { + unsigned long tbr; + unsigned long gr[64]; + }; +}; + +struct user_fpmedia_regs +{ + /* FP/Media registers */ + unsigned long fr[64]; + unsigned long fner[2]; + unsigned long msr[2]; + unsigned long acc[8]; + unsigned char accg[8]; + unsigned long fsr[1]; +}; + +struct user_context +{ + struct user_int_regs i; + struct user_fpmedia_regs f; + + /* we provide a context extension so that we can save the regs for CPUs that + * implement many more of Fujitsu's lavish register spec + */ + void *extension; +} __attribute__((aligned(8))); + +struct frv_frame0 { + union { + struct pt_regs regs; + struct user_context uc; + }; + + struct frv_debug_regs debug; + +} __attribute__((aligned(32))); + +#endif + +#define __INT_GR(R) __OFFSET(__INT_GR0, (R)) + +#define __FPMEDIA_FR(R) __OFFSET(__FPMEDIA_FR0, (R)) +#define __FPMEDIA_FNER(R) __OFFSET(__FPMEDIA_FNER0, (R)) +#define __FPMEDIA_MSR(R) __OFFSET(__FPMEDIA_MSR0, (R)) +#define __FPMEDIA_ACC(R) __OFFSET(__FPMEDIA_ACC0, (R)) +#define __FPMEDIA_ACCG(R) __OFFSETC(__FPMEDIA_ACCG0, (R)) +#define __FPMEDIA_FSR(R) __OFFSET(__FPMEDIA_FSR0, (R)) + +#define __THREAD_GR(R) __OFFSET(__THREAD_GR16, (R) - 16) + +#endif /* _ASM_REGISTERS_H */ diff --git a/arch/frv/include/asm/resource.h b/arch/frv/include/asm/resource.h new file mode 100644 index 0000000..5fc6054 --- /dev/null +++ b/arch/frv/include/asm/resource.h @@ -0,0 +1,7 @@ +#ifndef _ASM_RESOURCE_H +#define _ASM_RESOURCE_H + +#include <asm-generic/resource.h> + +#endif /* _ASM_RESOURCE_H */ + diff --git a/arch/frv/include/asm/scatterlist.h b/arch/frv/include/asm/scatterlist.h new file mode 100644 index 0000000..4bca8a2 --- /dev/null +++ b/arch/frv/include/asm/scatterlist.h @@ -0,0 +1,46 @@ +#ifndef _ASM_SCATTERLIST_H +#define _ASM_SCATTERLIST_H + +#include <asm/types.h> + +/* + * Drivers must set either ->address or (preferred) page and ->offset + * to indicate where data must be transferred to/from. + * + * Using page is recommended since it handles highmem data as well as + * low mem. ->address is restricted to data which has a virtual mapping, and + * it will go away in the future. Updating to page can be automated very + * easily -- something like + * + * sg->address = some_ptr; + * + * can be rewritten as + * + * sg_set_buf(sg, some_ptr, length); + * + * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens + */ +struct scatterlist { +#ifdef CONFIG_DEBUG_SG + unsigned long sg_magic; +#endif + unsigned long page_link; + unsigned int offset; /* for highmem, page offset */ + + dma_addr_t dma_address; + unsigned int length; +}; + +/* + * These macros should be used after a pci_map_sg call has been done + * to get bus addresses of each of the SG entries and their lengths. + * You should only work with the number of sg entries pci_map_sg + * returns, or alternatively stop on the first sg_dma_len(sg) which + * is 0. + */ +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->length) + +#define ISA_DMA_THRESHOLD (0xffffffffUL) + +#endif /* !_ASM_SCATTERLIST_H */ diff --git a/arch/frv/include/asm/sections.h b/arch/frv/include/asm/sections.h new file mode 100644 index 0000000..17d0fb1 --- /dev/null +++ b/arch/frv/include/asm/sections.h @@ -0,0 +1,46 @@ +/* sections.h: linkage layout variables + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_SECTIONS_H +#define _ASM_SECTIONS_H + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> +#include <asm-generic/sections.h> + +#ifdef __KERNEL__ + +/* + * we don't want to put variables in the GP-REL section if they're not used very much - that would + * be waste since GP-REL addressing is limited to GP16+/-2048 + */ +#define __nongpreldata __attribute__((section(".data"))) +#define __nongprelbss __attribute__((section(".bss"))) + +/* + * linker symbols + */ +extern const void __kernel_image_start, __kernel_image_end, __page_offset; + +extern unsigned long __nongprelbss memory_start; +extern unsigned long __nongprelbss memory_end; +extern unsigned long __nongprelbss rom_length; + +/* determine if we're running from ROM */ +static inline int is_in_rom(unsigned long addr) +{ + return 0; /* default case: not in ROM */ +} + +#endif +#endif +#endif /* _ASM_SECTIONS_H */ diff --git a/arch/frv/include/asm/segment.h b/arch/frv/include/asm/segment.h new file mode 100644 index 0000000..e3616a6 --- /dev/null +++ b/arch/frv/include/asm/segment.h @@ -0,0 +1,45 @@ +/* segment.h: MMU segment settings + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_SEGMENT_H +#define _ASM_SEGMENT_H + + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned long seg; +} mm_segment_t; + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + +#define KERNEL_DS MAKE_MM_SEG(0xdfffffffUL) + +#ifdef CONFIG_MMU +#define USER_DS MAKE_MM_SEG(TASK_SIZE - 1) +#else +#define USER_DS KERNEL_DS +#endif + +#define get_ds() (KERNEL_DS) +#define get_fs() (__current_thread_info->addr_limit) +#define segment_eq(a,b) ((a).seg == (b).seg) +#define __kernel_ds_p() segment_eq(get_fs(), KERNEL_DS) +#define get_addr_limit() (get_fs().seg) + +#define set_fs(_x) \ +do { \ + __current_thread_info->addr_limit = (_x); \ +} while(0) + + +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_SEGMENT_H */ diff --git a/arch/frv/include/asm/sembuf.h b/arch/frv/include/asm/sembuf.h new file mode 100644 index 0000000..164b127 --- /dev/null +++ b/arch/frv/include/asm/sembuf.h @@ -0,0 +1,26 @@ +#ifndef _ASM_SEMBUF_H +#define _ASM_SEMBUF_H + +/* + * The semid64_ds structure for FR-V architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _ASM_SEMBUF_H */ + diff --git a/arch/frv/include/asm/serial-regs.h b/arch/frv/include/asm/serial-regs.h new file mode 100644 index 0000000..e1286bd --- /dev/null +++ b/arch/frv/include/asm/serial-regs.h @@ -0,0 +1,44 @@ +/* serial-regs.h: serial port registers + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_SERIAL_REGS_H +#define _ASM_SERIAL_REGS_H + +#include <linux/serial_reg.h> +#include <asm/irc-regs.h> + +#define SERIAL_ICLK 33333333 /* the target serial input clock */ +#define UART0_BASE 0xfeff9c00 +#define UART1_BASE 0xfeff9c40 + +#define __get_UART0(R) ({ __reg(UART0_BASE + (R) * 8) >> 24; }) +#define __get_UART1(R) ({ __reg(UART1_BASE + (R) * 8) >> 24; }) +#define __set_UART0(R,V) do { __reg(UART0_BASE + (R) * 8) = (V) << 24; } while(0) +#define __set_UART1(R,V) do { __reg(UART1_BASE + (R) * 8) = (V) << 24; } while(0) + +#define __get_UART0_LSR() ({ __get_UART0(UART_LSR); }) +#define __get_UART1_LSR() ({ __get_UART1(UART_LSR); }) + +#define __set_UART0_IER(V) __set_UART0(UART_IER,(V)) +#define __set_UART1_IER(V) __set_UART1(UART_IER,(V)) + +/* serial prescaler select register */ +#define __get_UCPSR() ({ *(volatile unsigned long *)(0xfeff9c90); }) +#define __set_UCPSR(V) do { *(volatile unsigned long *)(0xfeff9c90) = (V); } while(0) +#define UCPSR_SELECT0 0x07000000 +#define UCPSR_SELECT1 0x38000000 + +/* serial prescaler base value register */ +#define __get_UCPVR() ({ *(volatile unsigned long *)(0xfeff9c98); mb(); }) +#define __set_UCPVR(V) do { *(volatile unsigned long *)(0xfeff9c98) = (V) << 24; mb(); } while(0) + + +#endif /* _ASM_SERIAL_REGS_H */ diff --git a/arch/frv/include/asm/serial.h b/arch/frv/include/asm/serial.h new file mode 100644 index 0000000..dbb8259 --- /dev/null +++ b/arch/frv/include/asm/serial.h @@ -0,0 +1,18 @@ +/* + * serial.h + * + * Copyright (C) 2003 Develer S.r.l. (http://www.develer.com/) + * Author: Bernardo Innocenti <bernie@codewiz.org> + * + * Based on linux/include/asm-i386/serial.h + */ +#include <asm/serial-regs.h> + +/* + * the base baud is derived from the clock speed and so is variable + */ +#define BASE_BAUD 0 + +#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF + +#define SERIAL_PORT_DFNS diff --git a/arch/frv/include/asm/setup.h b/arch/frv/include/asm/setup.h new file mode 100644 index 0000000..afd787c --- /dev/null +++ b/arch/frv/include/asm/setup.h @@ -0,0 +1,31 @@ +/* setup.h: setup stuff + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_SETUP_H +#define _ASM_SETUP_H + +#define COMMAND_LINE_SIZE 512 + +#ifdef __KERNEL__ + +#include <linux/init.h> + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_MMU +extern unsigned long __initdata num_mappedpages; +#endif + +#endif /* !__ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_SETUP_H */ diff --git a/arch/frv/include/asm/shmbuf.h b/arch/frv/include/asm/shmbuf.h new file mode 100644 index 0000000..4c6e711 --- /dev/null +++ b/arch/frv/include/asm/shmbuf.h @@ -0,0 +1,43 @@ +#ifndef _ASM_SHMBUF_H +#define _ASM_SHMBUF_H + +/* + * The shmid64_ds structure for FR-V architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _ASM_SHMBUF_H */ + diff --git a/arch/frv/include/asm/shmparam.h b/arch/frv/include/asm/shmparam.h new file mode 100644 index 0000000..ab71100 --- /dev/null +++ b/arch/frv/include/asm/shmparam.h @@ -0,0 +1,7 @@ +#ifndef _ASM_SHMPARAM_H +#define _ASM_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _ASM_SHMPARAM_H */ + diff --git a/arch/frv/include/asm/sigcontext.h b/arch/frv/include/asm/sigcontext.h new file mode 100644 index 0000000..3b263f3 --- /dev/null +++ b/arch/frv/include/asm/sigcontext.h @@ -0,0 +1,26 @@ +/* sigcontext.h: FRV signal context + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_SIGCONTEXT_H +#define _ASM_SIGCONTEXT_H + +#include <asm/registers.h> + +/* + * Signal context structure - contains all info to do with the state + * before the signal handler was invoked. Note: only add new entries + * to the end of the structure. + */ +struct sigcontext { + struct user_context sc_context; + unsigned long sc_oldmask; /* old sigmask */ +} __attribute__((aligned(8))); + +#endif diff --git a/arch/frv/include/asm/siginfo.h b/arch/frv/include/asm/siginfo.h new file mode 100644 index 0000000..d3fd1ca --- /dev/null +++ b/arch/frv/include/asm/siginfo.h @@ -0,0 +1,12 @@ +#ifndef _ASM_SIGINFO_H +#define _ASM_SIGINFO_H + +#include <linux/types.h> +#include <asm-generic/siginfo.h> + +#define FPE_MDAOVF (__SI_FAULT|9) /* media overflow */ +#undef NSIGFPE +#define NSIGFPE 9 + +#endif + diff --git a/arch/frv/include/asm/signal.h b/arch/frv/include/asm/signal.h new file mode 100644 index 0000000..2079197 --- /dev/null +++ b/arch/frv/include/asm/signal.h @@ -0,0 +1,161 @@ +#ifndef _ASM_SIGNAL_H +#define _ASM_SIGNAL_H + +#include <linux/types.h> + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX (_NSIG-1) + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +#define SA_RESTORER 0x04000000 + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include <asm-generic/signal.h> + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + __sigrestore_t sa_restorer; +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + __sigrestore_t sa_restorer; + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + +#ifdef __KERNEL__ + +#include <asm/sigcontext.h> +#undef __HAVE_ARCH_SIG_BITOPS + +#endif /* __KERNEL__ */ + +#endif /* _ASM_SIGNAL_H */ diff --git a/arch/frv/include/asm/smp.h b/arch/frv/include/asm/smp.h new file mode 100644 index 0000000..38349ec --- /dev/null +++ b/arch/frv/include/asm/smp.h @@ -0,0 +1,9 @@ +#ifndef __ASM_SMP_H +#define __ASM_SMP_H + + +#ifdef CONFIG_SMP +#error SMP not supported +#endif + +#endif diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h new file mode 100644 index 0000000..57c3d40 --- /dev/null +++ b/arch/frv/include/asm/socket.h @@ -0,0 +1,61 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockopt(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_SNDBUFFORCE 32 +#define SO_RCVBUFFORCE 33 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 + +#define SO_PEERSEC 31 +#define SO_PASSSEC 34 +#define SO_TIMESTAMPNS 35 +#define SCM_TIMESTAMPNS SO_TIMESTAMPNS + +#define SO_MARK 36 + +#define SO_TIMESTAMPING 37 +#define SCM_TIMESTAMPING SO_TIMESTAMPING + +#endif /* _ASM_SOCKET_H */ + diff --git a/arch/frv/include/asm/sockios.h b/arch/frv/include/asm/sockios.h new file mode 100644 index 0000000..5dbdd13 --- /dev/null +++ b/arch/frv/include/asm/sockios.h @@ -0,0 +1,14 @@ +#ifndef _ASM_SOCKIOS__ +#define _ASM_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ +#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + +#endif /* _ASM_SOCKIOS__ */ + diff --git a/arch/frv/include/asm/spinlock.h b/arch/frv/include/asm/spinlock.h new file mode 100644 index 0000000..fe385f4 --- /dev/null +++ b/arch/frv/include/asm/spinlock.h @@ -0,0 +1,17 @@ +/* spinlock.h: spinlocks for FR-V + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_SPINLOCK_H +#define _ASM_SPINLOCK_H + +#error no spinlocks for FR-V yet + +#endif /* _ASM_SPINLOCK_H */ diff --git a/arch/frv/include/asm/spr-regs.h b/arch/frv/include/asm/spr-regs.h new file mode 100644 index 0000000..01e6af5 --- /dev/null +++ b/arch/frv/include/asm/spr-regs.h @@ -0,0 +1,416 @@ +/* spr-regs.h: special-purpose registers on the FRV + * + * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_SPR_REGS_H +#define _ASM_SPR_REGS_H + +/* + * PSR - Processor Status Register + */ +#define PSR_ET 0x00000001 /* enable interrupts/exceptions flag */ +#define PSR_PS 0x00000002 /* previous supervisor mode flag */ +#define PSR_S 0x00000004 /* supervisor mode flag */ +#define PSR_PIL 0x00000078 /* processor external interrupt level */ +#define PSR_PIL_0 0x00000000 /* - no interrupt in progress */ +#define PSR_PIL_13 0x00000068 /* - debugging only */ +#define PSR_PIL_14 0x00000070 /* - debugging in progress */ +#define PSR_PIL_15 0x00000078 /* - NMI in progress */ +#define PSR_EM 0x00000080 /* enable media operation */ +#define PSR_EF 0x00000100 /* enable FPU operation */ +#define PSR_BE 0x00001000 /* endianness mode */ +#define PSR_BE_LE 0x00000000 /* - little endian mode */ +#define PSR_BE_BE 0x00001000 /* - big endian mode */ +#define PSR_CM 0x00002000 /* conditional mode */ +#define PSR_NEM 0x00004000 /* non-excepting mode */ +#define PSR_ICE 0x00010000 /* in-circuit emulation mode */ +#define PSR_VERSION_SHIFT 24 /* CPU silicon ID */ +#define PSR_IMPLE_SHIFT 28 /* CPU core ID */ + +#define PSR_VERSION(psr) (((psr) >> PSR_VERSION_SHIFT) & 0xf) +#define PSR_IMPLE(psr) (((psr) >> PSR_IMPLE_SHIFT) & 0xf) + +#define PSR_IMPLE_FR401 0x2 +#define PSR_VERSION_FR401_MB93401 0x0 +#define PSR_VERSION_FR401_MB93401A 0x1 +#define PSR_VERSION_FR401_MB93403 0x2 + +#define PSR_IMPLE_FR405 0x4 +#define PSR_VERSION_FR405_MB93405 0x0 + +#define PSR_IMPLE_FR451 0x5 +#define PSR_VERSION_FR451_MB93451 0x0 + +#define PSR_IMPLE_FR501 0x1 +#define PSR_VERSION_FR501_MB93501 0x1 +#define PSR_VERSION_FR501_MB93501A 0x2 + +#define PSR_IMPLE_FR551 0x3 +#define PSR_VERSION_FR551_MB93555 0x1 + +#define __get_PSR() ({ unsigned long x; asm volatile("movsg psr,%0" : "=r"(x)); x; }) +#define __set_PSR(V) do { asm volatile("movgs %0,psr" : : "r"(V)); } while(0) + +/* + * TBR - Trap Base Register + */ +#define TBR_TT 0x00000ff0 +#define TBR_TT_INSTR_MMU_MISS (0x01 << 4) +#define TBR_TT_INSTR_ACC_ERROR (0x02 << 4) +#define TBR_TT_INSTR_ACC_EXCEP (0x03 << 4) +#define TBR_TT_PRIV_INSTR (0x06 << 4) +#define TBR_TT_ILLEGAL_INSTR (0x07 << 4) +#define TBR_TT_FP_EXCEPTION (0x0d << 4) +#define TBR_TT_MP_EXCEPTION (0x0e << 4) +#define TBR_TT_DATA_ACC_ERROR (0x11 << 4) +#define TBR_TT_DATA_MMU_MISS (0x12 << 4) +#define TBR_TT_DATA_ACC_EXCEP (0x13 << 4) +#define TBR_TT_DATA_STR_ERROR (0x14 << 4) +#define TBR_TT_DIVISION_EXCEP (0x17 << 4) +#define TBR_TT_COMMIT_EXCEP (0x19 << 4) +#define TBR_TT_INSTR_TLB_MISS (0x1a << 4) +#define TBR_TT_DATA_TLB_MISS (0x1b << 4) +#define TBR_TT_DATA_DAT_EXCEP (0x1d << 4) +#define TBR_TT_DECREMENT_TIMER (0x1f << 4) +#define TBR_TT_COMPOUND_EXCEP (0x20 << 4) +#define TBR_TT_INTERRUPT_1 (0x21 << 4) +#define TBR_TT_INTERRUPT_2 (0x22 << 4) +#define TBR_TT_INTERRUPT_3 (0x23 << 4) +#define TBR_TT_INTERRUPT_4 (0x24 << 4) +#define TBR_TT_INTERRUPT_5 (0x25 << 4) +#define TBR_TT_INTERRUPT_6 (0x26 << 4) +#define TBR_TT_INTERRUPT_7 (0x27 << 4) +#define TBR_TT_INTERRUPT_8 (0x28 << 4) +#define TBR_TT_INTERRUPT_9 (0x29 << 4) +#define TBR_TT_INTERRUPT_10 (0x2a << 4) +#define TBR_TT_INTERRUPT_11 (0x2b << 4) +#define TBR_TT_INTERRUPT_12 (0x2c << 4) +#define TBR_TT_INTERRUPT_13 (0x2d << 4) +#define TBR_TT_INTERRUPT_14 (0x2e << 4) +#define TBR_TT_INTERRUPT_15 (0x2f << 4) +#define TBR_TT_TRAP0 (0x80 << 4) +#define TBR_TT_TRAP1 (0x81 << 4) +#define TBR_TT_TRAP2 (0x82 << 4) +#define TBR_TT_TRAP3 (0x83 << 4) +#define TBR_TT_TRAP120 (0xf8 << 4) +#define TBR_TT_TRAP121 (0xf9 << 4) +#define TBR_TT_TRAP122 (0xfa << 4) +#define TBR_TT_TRAP123 (0xfb << 4) +#define TBR_TT_TRAP124 (0xfc << 4) +#define TBR_TT_TRAP125 (0xfd << 4) +#define TBR_TT_TRAP126 (0xfe << 4) +#define TBR_TT_BREAK (0xff << 4) + +#define TBR_TT_ATOMIC_CMPXCHG32 TBR_TT_TRAP120 +#define TBR_TT_ATOMIC_XCHG32 TBR_TT_TRAP121 +#define TBR_TT_ATOMIC_XOR TBR_TT_TRAP122 +#define TBR_TT_ATOMIC_OR TBR_TT_TRAP123 +#define TBR_TT_ATOMIC_AND TBR_TT_TRAP124 +#define TBR_TT_ATOMIC_SUB TBR_TT_TRAP125 +#define TBR_TT_ATOMIC_ADD TBR_TT_TRAP126 + +#define __get_TBR() ({ unsigned long x; asm volatile("movsg tbr,%0" : "=r"(x)); x; }) + +/* + * HSR0 - Hardware Status Register 0 + */ +#define HSR0_PDM 0x00000007 /* power down mode */ +#define HSR0_PDM_NORMAL 0x00000000 /* - normal mode */ +#define HSR0_PDM_CORE_SLEEP 0x00000001 /* - CPU core sleep mode */ +#define HSR0_PDM_BUS_SLEEP 0x00000003 /* - bus sleep mode */ +#define HSR0_PDM_PLL_RUN 0x00000005 /* - PLL run */ +#define HSR0_PDM_PLL_STOP 0x00000007 /* - PLL stop */ +#define HSR0_GRLE 0x00000040 /* GR lower register set enable */ +#define HSR0_GRHE 0x00000080 /* GR higher register set enable */ +#define HSR0_FRLE 0x00000100 /* FR lower register set enable */ +#define HSR0_FRHE 0x00000200 /* FR higher register set enable */ +#define HSR0_GRN 0x00000400 /* GR quantity */ +#define HSR0_GRN_64 0x00000000 /* - 64 GR registers */ +#define HSR0_GRN_32 0x00000400 /* - 32 GR registers */ +#define HSR0_FRN 0x00000800 /* FR quantity */ +#define HSR0_FRN_64 0x00000000 /* - 64 FR registers */ +#define HSR0_FRN_32 0x00000800 /* - 32 FR registers */ +#define HSR0_SA 0x00001000 /* start address (RAMBOOT#) */ +#define HSR0_ETMI 0x00008000 /* enable TIMERI (64-bit up timer) */ +#define HSR0_ETMD 0x00004000 /* enable TIMERD (32-bit down timer) */ +#define HSR0_PEDAT 0x00010000 /* previous DAT mode */ +#define HSR0_XEDAT 0x00020000 /* exception DAT mode */ +#define HSR0_EDAT 0x00080000 /* enable DAT mode */ +#define HSR0_RME 0x00400000 /* enable RAM mode */ +#define HSR0_EMEM 0x00800000 /* enable MMU_Miss mask */ +#define HSR0_EXMMU 0x01000000 /* enable extended MMU mode */ +#define HSR0_EDMMU 0x02000000 /* enable data MMU */ +#define HSR0_EIMMU 0x04000000 /* enable instruction MMU */ +#define HSR0_CBM 0x08000000 /* copy back mode */ +#define HSR0_CBM_WRITE_THRU 0x00000000 /* - write through */ +#define HSR0_CBM_COPY_BACK 0x08000000 /* - copy back */ +#define HSR0_NWA 0x10000000 /* no write allocate */ +#define HSR0_DCE 0x40000000 /* data cache enable */ +#define HSR0_ICE 0x80000000 /* instruction cache enable */ + +#define __get_HSR(R) ({ unsigned long x; asm volatile("movsg hsr"#R",%0" : "=r"(x)); x; }) +#define __set_HSR(R,V) do { asm volatile("movgs %0,hsr"#R : : "r"(V)); } while(0) + +/* + * CCR - Condition Codes Register + */ +#define CCR_FCC0 0x0000000f /* FP/Media condition 0 (fcc0 reg) */ +#define CCR_FCC1 0x000000f0 /* FP/Media condition 1 (fcc1 reg) */ +#define CCR_FCC2 0x00000f00 /* FP/Media condition 2 (fcc2 reg) */ +#define CCR_FCC3 0x0000f000 /* FP/Media condition 3 (fcc3 reg) */ +#define CCR_ICC0 0x000f0000 /* Integer condition 0 (icc0 reg) */ +#define CCR_ICC0_C 0x00010000 /* - Carry flag */ +#define CCR_ICC0_V 0x00020000 /* - Overflow flag */ +#define CCR_ICC0_Z 0x00040000 /* - Zero flag */ +#define CCR_ICC0_N 0x00080000 /* - Negative flag */ +#define CCR_ICC1 0x00f00000 /* Integer condition 1 (icc1 reg) */ +#define CCR_ICC2 0x0f000000 /* Integer condition 2 (icc2 reg) */ +#define CCR_ICC3 0xf0000000 /* Integer condition 3 (icc3 reg) */ + +/* + * CCCR - Condition Codes for Conditional Instructions Register + */ +#define CCCR_CC0 0x00000003 /* condition 0 (cc0 reg) */ +#define CCCR_CC0_FALSE 0x00000002 /* - condition is false */ +#define CCCR_CC0_TRUE 0x00000003 /* - condition is true */ +#define CCCR_CC1 0x0000000c /* condition 1 (cc1 reg) */ +#define CCCR_CC2 0x00000030 /* condition 2 (cc2 reg) */ +#define CCCR_CC3 0x000000c0 /* condition 3 (cc3 reg) */ +#define CCCR_CC4 0x00000300 /* condition 4 (cc4 reg) */ +#define CCCR_CC5 0x00000c00 /* condition 5 (cc5 reg) */ +#define CCCR_CC6 0x00003000 /* condition 6 (cc6 reg) */ +#define CCCR_CC7 0x0000c000 /* condition 7 (cc7 reg) */ + +/* + * ISR - Integer Status Register + */ +#define ISR_EMAM 0x00000001 /* memory misaligned access handling */ +#define ISR_EMAM_EXCEPTION 0x00000000 /* - generate exception */ +#define ISR_EMAM_FUDGE 0x00000001 /* - mask out invalid address bits */ +#define ISR_AEXC 0x00000004 /* accrued [overflow] exception */ +#define ISR_DTT 0x00000018 /* division type trap */ +#define ISR_DTT_IGNORE 0x00000000 /* - ignore division error */ +#define ISR_DTT_DIVBYZERO 0x00000008 /* - generate exception */ +#define ISR_DTT_OVERFLOW 0x00000010 /* - record overflow */ +#define ISR_EDE 0x00000020 /* enable division exception */ +#define ISR_PLI 0x20000000 /* pre-load instruction information */ +#define ISR_QI 0x80000000 /* quad data implementation information */ + +/* + * EPCR0 - Exception PC Register + */ +#define EPCR0_V 0x00000001 /* register content validity indicator */ +#define EPCR0_PC 0xfffffffc /* faulting instruction address */ + +/* + * ESR0/14/15 - Exception Status Register + */ +#define ESRx_VALID 0x00000001 /* register content validity indicator */ +#define ESRx_EC 0x0000003e /* exception type */ +#define ESRx_EC_DATA_STORE 0x00000000 /* - data_store_error */ +#define ESRx_EC_INSN_ACCESS 0x00000006 /* - instruction_access_error */ +#define ESRx_EC_PRIV_INSN 0x00000008 /* - privileged_instruction */ +#define ESRx_EC_ILL_INSN 0x0000000a /* - illegal_instruction */ +#define ESRx_EC_MP_EXCEP 0x0000001c /* - mp_exception */ +#define ESRx_EC_DATA_ACCESS 0x00000020 /* - data_access_error */ +#define ESRx_EC_DIVISION 0x00000026 /* - division_exception */ +#define ESRx_EC_ITLB_MISS 0x00000034 /* - instruction_access_TLB_miss */ +#define ESRx_EC_DTLB_MISS 0x00000036 /* - data_access_TLB_miss */ +#define ESRx_EC_DATA_ACCESS_DAT 0x0000003a /* - data_access_DAT_exception */ + +#define ESR0_IAEC 0x00000100 /* info for instruction-access-exception */ +#define ESR0_IAEC_RESV 0x00000000 /* - reserved */ +#define ESR0_IAEC_PROT_VIOL 0x00000100 /* - protection violation */ + +#define ESR0_ATXC 0x00f00000 /* address translation exception code */ +#define ESR0_ATXC_MMU_MISS 0x00000000 /* - MMU miss exception and more (?) */ +#define ESR0_ATXC_MULTI_DAT 0x00800000 /* - multiple DAT entry hit */ +#define ESR0_ATXC_MULTI_SAT 0x00900000 /* - multiple SAT entry hit */ +#define ESR0_ATXC_AMRTLB_MISS 0x00a00000 /* - MMU/TLB miss exception */ +#define ESR0_ATXC_PRIV_EXCEP 0x00c00000 /* - privilege protection fault */ +#define ESR0_ATXC_WP_EXCEP 0x00d00000 /* - write protection fault */ + +#define ESR0_EAV 0x00000800 /* true if EAR0 register valid */ +#define ESR15_EAV 0x00000800 /* true if EAR15 register valid */ + +/* + * ESFR1 - Exception Status Valid Flag Register + */ +#define ESFR1_ESR0 0x00000001 /* true if ESR0 is valid */ +#define ESFR1_ESR14 0x00004000 /* true if ESR14 is valid */ +#define ESFR1_ESR15 0x00008000 /* true if ESR15 is valid */ + +/* + * MSR - Media Status Register + */ +#define MSR0_AOVF 0x00000001 /* overflow exception accrued */ +#define MSRx_OVF 0x00000002 /* overflow exception detected */ +#define MSRx_SIE 0x0000003c /* last SIMD instruction exception detected */ +#define MSRx_SIE_NONE 0x00000000 /* - none detected */ +#define MSRx_SIE_FRkHI_ACCk 0x00000020 /* - exception at FRkHI or ACCk */ +#define MSRx_SIE_FRkLO_ACCk1 0x00000010 /* - exception at FRkLO or ACCk+1 */ +#define MSRx_SIE_FRk1HI_ACCk2 0x00000008 /* - exception at FRk+1HI or ACCk+2 */ +#define MSRx_SIE_FRk1LO_ACCk3 0x00000004 /* - exception at FRk+1LO or ACCk+3 */ +#define MSR0_MTT 0x00007000 /* type of last media trap detected */ +#define MSR0_MTT_NONE 0x00000000 /* - none detected */ +#define MSR0_MTT_OVERFLOW 0x00001000 /* - overflow detected */ +#define MSR0_HI 0x00c00000 /* hardware implementation */ +#define MSR0_HI_ROUNDING 0x00000000 /* - rounding mode */ +#define MSR0_HI_NONROUNDING 0x00c00000 /* - non-rounding mode */ +#define MSR0_EMCI 0x01000000 /* enable media custom instructions */ +#define MSR0_SRDAV 0x10000000 /* select rounding mode of MAVEH */ +#define MSR0_SRDAV_RDAV 0x00000000 /* - controlled by MSR.RDAV */ +#define MSR0_SRDAV_RD 0x10000000 /* - controlled by MSR.RD */ +#define MSR0_RDAV 0x20000000 /* rounding mode of MAVEH */ +#define MSR0_RDAV_NEAREST_MI 0x00000000 /* - round to nearest minus */ +#define MSR0_RDAV_NEAREST_PL 0x20000000 /* - round to nearest plus */ +#define MSR0_RD 0xc0000000 /* rounding mode */ +#define MSR0_RD_NEAREST 0x00000000 /* - nearest */ +#define MSR0_RD_ZERO 0x40000000 /* - zero */ +#define MSR0_RD_POS_INF 0x80000000 /* - postive infinity */ +#define MSR0_RD_NEG_INF 0xc0000000 /* - negative infinity */ + +/* + * IAMPR0-7 - Instruction Address Mapping Register + * DAMPR0-7 - Data Address Mapping Register + */ +#define xAMPRx_V 0x00000001 /* register content validity indicator */ +#define DAMPRx_WP 0x00000002 /* write protect */ +#define DAMPRx_WP_RW 0x00000000 /* - read/write */ +#define DAMPRx_WP_RO 0x00000002 /* - read-only */ +#define xAMPRx_C 0x00000004 /* cached/uncached */ +#define xAMPRx_C_CACHED 0x00000000 /* - cached */ +#define xAMPRx_C_UNCACHED 0x00000004 /* - uncached */ +#define xAMPRx_S 0x00000008 /* supervisor only */ +#define xAMPRx_S_USER 0x00000000 /* - userspace can access */ +#define xAMPRx_S_KERNEL 0x00000008 /* - kernel only */ +#define xAMPRx_SS 0x000000f0 /* segment size */ +#define xAMPRx_SS_16Kb 0x00000000 /* - 16 kilobytes */ +#define xAMPRx_SS_64Kb 0x00000010 /* - 64 kilobytes */ +#define xAMPRx_SS_256Kb 0x00000020 /* - 256 kilobytes */ +#define xAMPRx_SS_1Mb 0x00000030 /* - 1 megabyte */ +#define xAMPRx_SS_2Mb 0x00000040 /* - 2 megabytes */ +#define xAMPRx_SS_4Mb 0x00000050 /* - 4 megabytes */ +#define xAMPRx_SS_8Mb 0x00000060 /* - 8 megabytes */ +#define xAMPRx_SS_16Mb 0x00000070 /* - 16 megabytes */ +#define xAMPRx_SS_32Mb 0x00000080 /* - 32 megabytes */ +#define xAMPRx_SS_64Mb 0x00000090 /* - 64 megabytes */ +#define xAMPRx_SS_128Mb 0x000000a0 /* - 128 megabytes */ +#define xAMPRx_SS_256Mb 0x000000b0 /* - 256 megabytes */ +#define xAMPRx_SS_512Mb 0x000000c0 /* - 512 megabytes */ +#define xAMPRx_RESERVED8 0x00000100 /* reserved bit */ +#define xAMPRx_NG 0x00000200 /* non-global */ +#define xAMPRx_L 0x00000400 /* locked */ +#define xAMPRx_M 0x00000800 /* modified */ +#define xAMPRx_D 0x00001000 /* DAT entry */ +#define xAMPRx_RESERVED13 0x00002000 /* reserved bit */ +#define xAMPRx_PPFN 0xfff00000 /* physical page frame number */ + +#define xAMPRx_V_BIT 0 +#define DAMPRx_WP_BIT 1 +#define xAMPRx_C_BIT 2 +#define xAMPRx_S_BIT 3 +#define xAMPRx_RESERVED8_BIT 8 +#define xAMPRx_NG_BIT 9 +#define xAMPRx_L_BIT 10 +#define xAMPRx_M_BIT 11 +#define xAMPRx_D_BIT 12 +#define xAMPRx_RESERVED13_BIT 13 + +#define __get_IAMPR(R) ({ unsigned long x; asm volatile("movsg iampr"#R",%0" : "=r"(x)); x; }) +#define __get_DAMPR(R) ({ unsigned long x; asm volatile("movsg dampr"#R",%0" : "=r"(x)); x; }) + +#define __get_IAMLR(R) ({ unsigned long x; asm volatile("movsg iamlr"#R",%0" : "=r"(x)); x; }) +#define __get_DAMLR(R) ({ unsigned long x; asm volatile("movsg damlr"#R",%0" : "=r"(x)); x; }) + +#define __set_IAMPR(R,V) do { asm volatile("movgs %0,iampr"#R : : "r"(V)); } while(0) +#define __set_DAMPR(R,V) do { asm volatile("movgs %0,dampr"#R : : "r"(V)); } while(0) + +#define __set_IAMLR(R,V) do { asm volatile("movgs %0,iamlr"#R : : "r"(V)); } while(0) +#define __set_DAMLR(R,V) do { asm volatile("movgs %0,damlr"#R : : "r"(V)); } while(0) + +#define save_dampr(R, _dampr) \ +do { \ + asm volatile("movsg dampr"R",%0" : "=r"(_dampr)); \ +} while(0) + +#define restore_dampr(R, _dampr) \ +do { \ + asm volatile("movgs %0,dampr"R :: "r"(_dampr)); \ +} while(0) + +/* + * AMCR - Address Mapping Control Register + */ +#define AMCR_IAMRN 0x000000ff /* quantity of IAMPR registers */ +#define AMCR_DAMRN 0x0000ff00 /* quantity of DAMPR registers */ + +/* + * TTBR - Address Translation Table Base Register + */ +#define __get_TTBR() ({ unsigned long x; asm volatile("movsg ttbr,%0" : "=r"(x)); x; }) + +/* + * TPXR - TLB Probe Extend Register + */ +#define TPXR_E 0x00000001 +#define TPXR_LMAX_SHIFT 20 +#define TPXR_LMAX_SMASK 0xf +#define TPXR_WMAX_SHIFT 24 +#define TPXR_WMAX_SMASK 0xf +#define TPXR_WAY_SHIFT 28 +#define TPXR_WAY_SMASK 0xf + +/* + * DCR - Debug Control Register + */ +#define DCR_IBCE3 0x00000001 /* break on conditional insn pointed to by IBAR3 */ +#define DCR_IBE3 0x00000002 /* break on insn pointed to by IBAR3 */ +#define DCR_IBCE1 0x00000004 /* break on conditional insn pointed to by IBAR2 */ +#define DCR_IBE1 0x00000008 /* break on insn pointed to by IBAR2 */ +#define DCR_IBCE2 0x00000010 /* break on conditional insn pointed to by IBAR1 */ +#define DCR_IBE2 0x00000020 /* break on insn pointed to by IBAR1 */ +#define DCR_IBCE0 0x00000040 /* break on conditional insn pointed to by IBAR0 */ +#define DCR_IBE0 0x00000080 /* break on insn pointed to by IBAR0 */ + +#define DCR_DDBE1 0x00004000 /* use DBDR1x when checking DBAR1 */ +#define DCR_DWBE1 0x00008000 /* break on store to address in DBAR1/DBMR1x */ +#define DCR_DRBE1 0x00010000 /* break on load from address in DBAR1/DBMR1x */ +#define DCR_DDBE0 0x00020000 /* use DBDR0x when checking DBAR0 */ +#define DCR_DWBE0 0x00040000 /* break on store to address in DBAR0/DBMR0x */ +#define DCR_DRBE0 0x00080000 /* break on load from address in DBAR0/DBMR0x */ + +#define DCR_EIM 0x0c000000 /* external interrupt disable */ +#define DCR_IBM 0x10000000 /* instruction break disable */ +#define DCR_SE 0x20000000 /* single step enable */ +#define DCR_EBE 0x40000000 /* exception break enable */ + +/* + * BRR - Break Interrupt Request Register + */ +#define BRR_ST 0x00000001 /* single-step detected */ +#define BRR_SB 0x00000002 /* break instruction detected */ +#define BRR_BB 0x00000004 /* branch with hint detected */ +#define BRR_CBB 0x00000008 /* branch to LR detected */ +#define BRR_IBx 0x000000f0 /* hardware breakpoint detected */ +#define BRR_DBx 0x00000f00 /* hardware watchpoint detected */ +#define BRR_DBNEx 0x0000f000 /* ? */ +#define BRR_EBTT 0x00ff0000 /* trap type of exception break */ +#define BRR_TB 0x10000000 /* external break request detected */ +#define BRR_CB 0x20000000 /* ICE break command detected */ +#define BRR_EB 0x40000000 /* exception break detected */ + +/* + * BPSR - Break PSR Save Register + */ +#define BPSR_BET 0x00000001 /* former PSR.ET */ +#define BPSR_BS 0x00001000 /* former PSR.S */ + +#endif /* _ASM_SPR_REGS_H */ diff --git a/arch/frv/include/asm/stat.h b/arch/frv/include/asm/stat.h new file mode 100644 index 0000000..ce56de9 --- /dev/null +++ b/arch/frv/include/asm/stat.h @@ -0,0 +1,100 @@ +#ifndef _ASM_STAT_H +#define _ASM_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +/* This matches struct stat in uClibc/glibc. */ +struct stat { + unsigned char __pad1[6]; + unsigned short st_dev; + + unsigned long __pad2; + unsigned long st_ino; + + unsigned short __pad3; + unsigned short st_mode; + unsigned short __pad4; + unsigned short st_nlink; + + unsigned short __pad5; + unsigned short st_uid; + unsigned short __pad6; + unsigned short st_gid; + + unsigned char __pad7[6]; + unsigned short st_rdev; + + unsigned long __pad8; + unsigned long st_size; + + unsigned long __pad9; /* align 64-bit st_blocks to 2-word */ + unsigned long st_blksize; + + unsigned long __pad10; /* future possible st_blocks high bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + + unsigned long __unused1; + unsigned long st_atime; + + unsigned long __unused2; + unsigned long st_mtime; + + unsigned long __unused3; + unsigned long st_ctime; + + unsigned long long __unused4; +}; + +/* This matches struct stat64 in uClibc/glibc. The layout is exactly + the same as that of struct stat above, with 64-bit types taking up + space that was formerly used by padding. stat syscalls are still + different from stat64, though, in that the former tests for + overflow. */ +struct stat64 { + unsigned char __pad1[6]; + unsigned short st_dev; + + unsigned long long st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned char __pad2[6]; + unsigned short st_rdev; + + long long st_size; + + unsigned long __pad3; /* align 64-bit st_blocks to 2-word */ + unsigned long st_blksize; + + unsigned long __pad4; /* future possible st_blocks high bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + + unsigned long st_atime_nsec; + unsigned long st_atime; + + unsigned int st_mtime_nsec; + unsigned long st_mtime; + + unsigned long st_ctime_nsec; + unsigned long st_ctime; + + unsigned long long __unused4; +}; + +#endif /* _ASM_STAT_H */ diff --git a/arch/frv/include/asm/statfs.h b/arch/frv/include/asm/statfs.h new file mode 100644 index 0000000..741f586 --- /dev/null +++ b/arch/frv/include/asm/statfs.h @@ -0,0 +1,7 @@ +#ifndef _ASM_STATFS_H +#define _ASM_STATFS_H + +#include <asm-generic/statfs.h> + +#endif /* _ASM_STATFS_H */ + diff --git a/arch/frv/include/asm/string.h b/arch/frv/include/asm/string.h new file mode 100644 index 0000000..5ed310f --- /dev/null +++ b/arch/frv/include/asm/string.h @@ -0,0 +1,51 @@ +/* string.h: FRV string handling + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_STRING_H_ +#define _ASM_STRING_H_ + +#ifdef __KERNEL__ /* only set these up for kernel code */ + +#define __HAVE_ARCH_MEMSET 1 +#define __HAVE_ARCH_MEMCPY 1 + +extern void *memset(void *, int, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t); + +#else /* KERNEL */ + +/* + * let user libraries deal with these, + * IMHO the kernel has no place defining these functions for user apps + */ + +#define __HAVE_ARCH_STRCPY 1 +#define __HAVE_ARCH_STRNCPY 1 +#define __HAVE_ARCH_STRCAT 1 +#define __HAVE_ARCH_STRNCAT 1 +#define __HAVE_ARCH_STRCMP 1 +#define __HAVE_ARCH_STRNCMP 1 +#define __HAVE_ARCH_STRNICMP 1 +#define __HAVE_ARCH_STRCHR 1 +#define __HAVE_ARCH_STRRCHR 1 +#define __HAVE_ARCH_STRSTR 1 +#define __HAVE_ARCH_STRLEN 1 +#define __HAVE_ARCH_STRNLEN 1 +#define __HAVE_ARCH_MEMSET 1 +#define __HAVE_ARCH_MEMCPY 1 +#define __HAVE_ARCH_MEMMOVE 1 +#define __HAVE_ARCH_MEMSCAN 1 +#define __HAVE_ARCH_MEMCMP 1 +#define __HAVE_ARCH_MEMCHR 1 +#define __HAVE_ARCH_STRTOK 1 + +#endif /* KERNEL */ +#endif /* _ASM_STRING_H_ */ diff --git a/arch/frv/include/asm/suspend.h b/arch/frv/include/asm/suspend.h new file mode 100644 index 0000000..5fa7b5a --- /dev/null +++ b/arch/frv/include/asm/suspend.h @@ -0,0 +1,20 @@ +/* suspend.h: suspension stuff + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_SUSPEND_H +#define _ASM_SUSPEND_H + +static inline int arch_prepare_suspend(void) +{ + return 0; +} + +#endif /* _ASM_SUSPEND_H */ diff --git a/arch/frv/include/asm/swab.h b/arch/frv/include/asm/swab.h new file mode 100644 index 0000000..f305834 --- /dev/null +++ b/arch/frv/include/asm/swab.h @@ -0,0 +1,10 @@ +#ifndef _ASM_SWAB_H +#define _ASM_SWAB_H + +#include <linux/types.h> + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __SWAB_64_THRU_32__ +#endif + +#endif /* _ASM_SWAB_H */ diff --git a/arch/frv/include/asm/system.h b/arch/frv/include/asm/system.h new file mode 100644 index 0000000..7742ec0 --- /dev/null +++ b/arch/frv/include/asm/system.h @@ -0,0 +1,301 @@ +/* system.h: FR-V CPU control definitions + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_SYSTEM_H +#define _ASM_SYSTEM_H + +#include <linux/types.h> +#include <linux/linkage.h> +#include <linux/kernel.h> + +struct thread_struct; + +/* + * switch_to(prev, next) should switch from task `prev' to `next' + * `prev' will never be the same as `next'. + * The `mb' is to tell GCC not to cache `current' across this call. + */ +extern asmlinkage +struct task_struct *__switch_to(struct thread_struct *prev_thread, + struct thread_struct *next_thread, + struct task_struct *prev); + +#define switch_to(prev, next, last) \ +do { \ + (prev)->thread.sched_lr = \ + (unsigned long) __builtin_return_address(0); \ + (last) = __switch_to(&(prev)->thread, &(next)->thread, (prev)); \ + mb(); \ +} while(0) + +/* + * interrupt flag manipulation + * - use virtual interrupt management since touching the PSR is slow + * - ICC2.Z: T if interrupts virtually disabled + * - ICC2.C: F if interrupts really disabled + * - if Z==1 upon interrupt: + * - C is set to 0 + * - interrupts are really disabled + * - entry.S returns immediately + * - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts + * - if taken, the trap: + * - sets ICC2.C + * - enables interrupts + */ +#define local_irq_disable() \ +do { \ + /* set Z flag, but don't change the C flag */ \ + asm volatile(" andcc gr0,gr0,gr0,icc2 \n" \ + : \ + : \ + : "memory", "icc2" \ + ); \ +} while(0) + +#define local_irq_enable() \ +do { \ + /* clear Z flag and then test the C flag */ \ + asm volatile(" oricc gr0,#1,gr0,icc2 \n" \ + " tihi icc2,gr0,#2 \n" \ + : \ + : \ + : "memory", "icc2" \ + ); \ +} while(0) + +#define local_save_flags(flags) \ +do { \ + typecheck(unsigned long, flags); \ + asm volatile("movsg ccr,%0" \ + : "=r"(flags) \ + : \ + : "memory"); \ + \ + /* shift ICC2.Z to bit 0 */ \ + flags >>= 26; \ + \ + /* make flags 1 if interrupts disabled, 0 otherwise */ \ + flags &= 1UL; \ +} while(0) + +#define irqs_disabled() \ + ({unsigned long flags; local_save_flags(flags); !!flags; }) + +#define local_irq_save(flags) \ +do { \ + typecheck(unsigned long, flags); \ + local_save_flags(flags); \ + local_irq_disable(); \ +} while(0) + +#define local_irq_restore(flags) \ +do { \ + typecheck(unsigned long, flags); \ + \ + /* load the Z flag by turning 1 if disabled into 0 if disabled \ + * and thus setting the Z flag but not the C flag */ \ + asm volatile(" xoricc %0,#1,gr0,icc2 \n" \ + /* then test Z=0 and C=0 */ \ + " tihi icc2,gr0,#2 \n" \ + : \ + : "r"(flags) \ + : "memory", "icc2" \ + ); \ + \ +} while(0) + +/* + * real interrupt flag manipulation + */ +#define __local_irq_disable() \ +do { \ + unsigned long psr; \ + asm volatile(" movsg psr,%0 \n" \ + " andi %0,%2,%0 \n" \ + " ori %0,%1,%0 \n" \ + " movgs %0,psr \n" \ + : "=r"(psr) \ + : "i" (PSR_PIL_14), "i" (~PSR_PIL) \ + : "memory"); \ +} while(0) + +#define __local_irq_enable() \ +do { \ + unsigned long psr; \ + asm volatile(" movsg psr,%0 \n" \ + " andi %0,%1,%0 \n" \ + " movgs %0,psr \n" \ + : "=r"(psr) \ + : "i" (~PSR_PIL) \ + : "memory"); \ +} while(0) + +#define __local_save_flags(flags) \ +do { \ + typecheck(unsigned long, flags); \ + asm("movsg psr,%0" \ + : "=r"(flags) \ + : \ + : "memory"); \ +} while(0) + +#define __local_irq_save(flags) \ +do { \ + unsigned long npsr; \ + typecheck(unsigned long, flags); \ + asm volatile(" movsg psr,%0 \n" \ + " andi %0,%3,%1 \n" \ + " ori %1,%2,%1 \n" \ + " movgs %1,psr \n" \ + : "=r"(flags), "=r"(npsr) \ + : "i" (PSR_PIL_14), "i" (~PSR_PIL) \ + : "memory"); \ +} while(0) + +#define __local_irq_restore(flags) \ +do { \ + typecheck(unsigned long, flags); \ + asm volatile(" movgs %0,psr \n" \ + : \ + : "r" (flags) \ + : "memory"); \ +} while(0) + +#define __irqs_disabled() \ + ((__get_PSR() & PSR_PIL) >= PSR_PIL_14) + +/* + * Force strict CPU ordering. + */ +#define nop() asm volatile ("nop"::) +#define mb() asm volatile ("membar" : : :"memory") +#define rmb() asm volatile ("membar" : : :"memory") +#define wmb() asm volatile ("membar" : : :"memory") +#define read_barrier_depends() do { } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() +#define set_mb(var, value) \ + do { xchg(&var, (value)); } while (0) +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do {} while(0) +#define set_mb(var, value) \ + do { var = (value); barrier(); } while (0) +#endif + +extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2))); +extern void free_initmem(void); + +#define arch_align_stack(x) (x) + +/*****************************************************************************/ +/* + * compare and conditionally exchange value with memory + * - if (*ptr == test) then orig = *ptr; *ptr = test; + * - if (*ptr != test) then orig = *ptr; + */ +#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS + +#define cmpxchg(ptr, test, new) \ +({ \ + __typeof__(ptr) __xg_ptr = (ptr); \ + __typeof__(*(ptr)) __xg_orig, __xg_tmp; \ + __typeof__(*(ptr)) __xg_test = (test); \ + __typeof__(*(ptr)) __xg_new = (new); \ + \ + switch (sizeof(__xg_orig)) { \ + case 4: \ + asm volatile( \ + "0: \n" \ + " orcc gr0,gr0,gr0,icc3 \n" \ + " ckeq icc3,cc7 \n" \ + " ld.p %M0,%1 \n" \ + " orcr cc7,cc7,cc3 \n" \ + " sub%I4cc %1,%4,%2,icc0 \n" \ + " bne icc0,#0,1f \n" \ + " cst.p %3,%M0 ,cc3,#1 \n" \ + " corcc gr29,gr29,gr0 ,cc3,#1 \n" \ + " beq icc3,#0,0b \n" \ + "1: \n" \ + : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \ + : "r"(__xg_new), "NPr"(__xg_test) \ + : "memory", "cc7", "cc3", "icc3", "icc0" \ + ); \ + break; \ + \ + default: \ + __xg_orig = (__typeof__(__xg_orig))0; \ + asm volatile("break"); \ + break; \ + } \ + \ + __xg_orig; \ +}) + +#else + +extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new); + +#define cmpxchg(ptr, test, new) \ +({ \ + __typeof__(ptr) __xg_ptr = (ptr); \ + __typeof__(*(ptr)) __xg_orig; \ + __typeof__(*(ptr)) __xg_test = (test); \ + __typeof__(*(ptr)) __xg_new = (new); \ + \ + switch (sizeof(__xg_orig)) { \ + case 4: __xg_orig = (__force __typeof__(*ptr)) \ + __cmpxchg_32((__force uint32_t *)__xg_ptr, \ + (__force uint32_t)__xg_test, \ + (__force uint32_t)__xg_new); break; \ + default: \ + __xg_orig = (__typeof__(__xg_orig))0; \ + asm volatile("break"); \ + break; \ + } \ + \ + __xg_orig; \ +}) + +#endif + +#include <asm-generic/cmpxchg-local.h> + +static inline unsigned long __cmpxchg_local(volatile void *ptr, + unsigned long old, + unsigned long new, int size) +{ + switch (size) { + case 4: + return cmpxchg((unsigned long *)ptr, old, new); + default: + return __cmpxchg_local_generic(ptr, old, new, size); + } + + return old; +} + +/* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make + * them available. + */ +#define cmpxchg_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +#endif /* _ASM_SYSTEM_H */ diff --git a/arch/frv/include/asm/termbits.h b/arch/frv/include/asm/termbits.h new file mode 100644 index 0000000..5568492 --- /dev/null +++ b/arch/frv/include/asm/termbits.h @@ -0,0 +1,202 @@ +#ifndef _ASM_TERMBITS_H__ +#define _ASM_TERMBITS_H__ + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define BOTHER 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* Input baud rate */ +#define CTVB 004000000000 /* VisioBraille Terminal flow control */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* _ASM_TERMBITS_H__ */ + diff --git a/arch/frv/include/asm/termios.h b/arch/frv/include/asm/termios.h new file mode 100644 index 0000000..a62fb58 --- /dev/null +++ b/arch/frv/include/asm/termios.h @@ -0,0 +1,58 @@ +#ifndef _ASM_TERMIOS_H +#define _ASM_TERMIOS_H + +#include <asm/termbits.h> +#include <asm/ioctls.h> + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */ + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +#ifdef __KERNEL__ +#include <asm-generic/termios.h> +#endif + +#endif /* _ASM_TERMIOS_H */ diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h new file mode 100644 index 0000000..bb53ab7 --- /dev/null +++ b/arch/frv/include/asm/thread_info.h @@ -0,0 +1,144 @@ +/* thread_info.h: description + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * Derived from include/asm-i386/thread_info.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +#include <asm/processor.h> +#endif + +#define THREAD_SIZE 8192 + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants must also be changed + */ +#ifndef __ASSEMBLY__ + +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + unsigned long status; /* thread-synchronous flags */ + __u32 cpu; /* current CPU */ + int preempt_count; /* 0 => preemptable, <0 => BUG */ + + mm_segment_t addr_limit; /* thread address space: + * 0-0xBFFFFFFF for user-thead + * 0-0xFFFFFFFF for kernel-thread + */ + struct restart_block restart_block; + + __u8 supervisor_stack[0]; +}; + +#else /* !__ASSEMBLY__ */ + +#include <asm/asm-offsets.h> + +#endif + +#define PREEMPT_ACTIVE 0x10000000 + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#ifndef __ASSEMBLY__ + +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* how to get the thread information struct from C */ +register struct thread_info *__current_thread_info asm("gr15"); + +#define current_thread_info() ({ __current_thread_info; }) + +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +/* thread information allocation */ +#ifdef CONFIG_DEBUG_STACK_USAGE +#define alloc_thread_info(tsk) \ + ({ \ + struct thread_info *ret; \ + \ + ret = kzalloc(THREAD_SIZE, GFP_KERNEL); \ + \ + ret; \ + }) +#else +#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) +#endif + +#define free_thread_info(info) kfree(info) + +#endif /* __ASSEMBLY__ */ + +/* + * thread information flags + * - these are process state flags that various assembly files may need to access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_SIGPENDING 1 /* signal pending */ +#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ +#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ +#define TIF_IRET 4 /* return with iret */ +#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ +#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_MEMDIE 17 /* OOM killer killed process */ +#define TIF_FREEZE 18 /* freezing for suspend */ + +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) +#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) +#define _TIF_IRET (1 << TIF_IRET) +#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) +#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) +#define _TIF_FREEZE (1 << TIF_FREEZE) + +#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ +#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ + +/* + * Thread-synchronous status. + * + * This is different from the flags in that nobody else + * ever touches our thread-synchronous status, so we don't + * have to worry about atomic accesses. + */ +#define TS_USEDFPM 0x0001 /* FPU/Media was used by this task this quantum (SMP) */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff --git a/arch/frv/include/asm/timer-regs.h b/arch/frv/include/asm/timer-regs.h new file mode 100644 index 0000000..6c5a871 --- /dev/null +++ b/arch/frv/include/asm/timer-regs.h @@ -0,0 +1,106 @@ +/* timer-regs.h: hardware timer register definitions + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_TIMER_REGS_H +#define _ASM_TIMER_REGS_H + +#include <asm/sections.h> + +extern unsigned long __nongprelbss __clkin_clock_speed_HZ; +extern unsigned long __nongprelbss __ext_bus_clock_speed_HZ; +extern unsigned long __nongprelbss __res_bus_clock_speed_HZ; +extern unsigned long __nongprelbss __sdram_clock_speed_HZ; +extern unsigned long __nongprelbss __core_bus_clock_speed_HZ; +extern unsigned long __nongprelbss __core_clock_speed_HZ; +extern unsigned long __nongprelbss __dsu_clock_speed_HZ; +extern unsigned long __nongprelbss __serial_clock_speed_HZ; + +#define __get_CLKC() ({ *(volatile unsigned long *)(0xfeff9a00); }) + +static inline void __set_CLKC(unsigned long v) +{ + int tmp; + + asm volatile(" st%I0.p %2,%M0 \n" + " setlos %3,%1 \n" + " membar \n" + "0: \n" + " subicc %1,#1,%1,icc0 \n" + " bnc icc0,#1,0b \n" + : "=m"(*(volatile unsigned long *) 0xfeff9a00), "=r"(tmp) + : "r"(v), "i"(256) + : "icc0"); +} + +#define __get_TCTR() ({ *(volatile unsigned long *)(0xfeff9418); }) +#define __get_TPRV() ({ *(volatile unsigned long *)(0xfeff9420); }) +#define __get_TPRCKSL() ({ *(volatile unsigned long *)(0xfeff9428); }) +#define __get_TCSR(T) ({ *(volatile unsigned long *)(0xfeff9400 + 8 * (T)); }) +#define __get_TxCKSL(T) ({ *(volatile unsigned long *)(0xfeff9430 + 8 * (T)); }) + +#define __get_TCSR_DATA(T) ({ __get_TCSR(T) >> 24; }) + +#define __set_TCTR(V) do { *(volatile unsigned long *)(0xfeff9418) = (V); mb(); } while(0) +#define __set_TPRV(V) do { *(volatile unsigned long *)(0xfeff9420) = (V) << 24; mb(); } while(0) +#define __set_TPRCKSL(V) do { *(volatile unsigned long *)(0xfeff9428) = (V); mb(); } while(0) +#define __set_TCSR(T,V) \ +do { *(volatile unsigned long *)(0xfeff9400 + 8 * (T)) = (V); mb(); } while(0) + +#define __set_TxCKSL(T,V) \ +do { *(volatile unsigned long *)(0xfeff9430 + 8 * (T)) = (V); mb(); } while(0) + +#define __set_TCSR_DATA(T,V) __set_TCSR(T, (V) << 24) +#define __set_TxCKSL_DATA(T,V) __set_TxCKSL(T, TxCKSL_EIGHT | __TxCKSL_SELECT((V))) + +/* clock control register */ +#define CLKC_CMODE 0x0f000000 +#define CLKC_SLPL 0x000f0000 +#define CLKC_P0 0x00000100 +#define CLKC_CM 0x00000003 + +#define CLKC_CMODE_s 24 + +/* timer control register - non-readback mode */ +#define TCTR_MODE_0 0x00000000 +#define TCTR_MODE_2 0x04000000 +#define TCTR_MODE_4 0x08000000 +#define TCTR_MODE_5 0x0a000000 +#define TCTR_RL_LATCH 0x00000000 +#define TCTR_RL_RW_LOW8 0x10000000 +#define TCTR_RL_RW_HIGH8 0x20000000 +#define TCTR_RL_RW_LH8 0x30000000 +#define TCTR_SC_CTR0 0x00000000 +#define TCTR_SC_CTR1 0x40000000 +#define TCTR_SC_CTR2 0x80000000 + +/* timer control register - readback mode */ +#define TCTR_CNT0 0x02000000 +#define TCTR_CNT1 0x04000000 +#define TCTR_CNT2 0x08000000 +#define TCTR_NSTATUS 0x10000000 +#define TCTR_NCOUNT 0x20000000 +#define TCTR_SC_READBACK 0xc0000000 + +/* timer control status registers - non-readback mode */ +#define TCSRx_DATA 0xff000000 + +/* timer control status registers - readback mode */ +#define TCSRx_OUTPUT 0x80000000 +#define TCSRx_NULLCOUNT 0x40000000 +#define TCSRx_RL 0x30000000 +#define TCSRx_MODE 0x07000000 + +/* timer clock select registers */ +#define TxCKSL_SELECT 0x0f000000 +#define __TxCKSL_SELECT(X) ((X) << 24) +#define TxCKSL_EIGHT 0xf0000000 + +#endif /* _ASM_TIMER_REGS_H */ diff --git a/arch/frv/include/asm/timex.h b/arch/frv/include/asm/timex.h new file mode 100644 index 0000000..a89bdde --- /dev/null +++ b/arch/frv/include/asm/timex.h @@ -0,0 +1,20 @@ +/* timex.h: FR-V architecture timex specifications + */ +#ifndef _ASM_TIMEX_H +#define _ASM_TIMEX_H + +#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ + +typedef unsigned long cycles_t; + +static inline cycles_t get_cycles(void) +{ + return 0; +} + +#define vxtime_lock() do {} while (0) +#define vxtime_unlock() do {} while (0) + +#endif + diff --git a/arch/frv/include/asm/tlb.h b/arch/frv/include/asm/tlb.h new file mode 100644 index 0000000..cd458eb --- /dev/null +++ b/arch/frv/include/asm/tlb.h @@ -0,0 +1,27 @@ +#ifndef _ASM_TLB_H +#define _ASM_TLB_H + +#include <asm/tlbflush.h> + +#ifdef CONFIG_MMU +extern void check_pgt_cache(void); +#else +#define check_pgt_cache() do {} while(0) +#endif + +/* + * we don't need any special per-pte or per-vma handling... + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +/* + * .. because we flush the whole mm when it fills up + */ +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + +#include <asm-generic/tlb.h> + +#endif /* _ASM_TLB_H */ + diff --git a/arch/frv/include/asm/tlbflush.h b/arch/frv/include/asm/tlbflush.h new file mode 100644 index 0000000..7ac5eaf --- /dev/null +++ b/arch/frv/include/asm/tlbflush.h @@ -0,0 +1,73 @@ +/* tlbflush.h: TLB flushing functions + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_TLBFLUSH_H +#define _ASM_TLBFLUSH_H + +#include <linux/mm.h> +#include <asm/processor.h> + +#ifdef CONFIG_MMU + +#ifndef __ASSEMBLY__ +extern void asmlinkage __flush_tlb_all(void); +extern void asmlinkage __flush_tlb_mm(unsigned long contextid); +extern void asmlinkage __flush_tlb_page(unsigned long contextid, unsigned long start); +extern void asmlinkage __flush_tlb_range(unsigned long contextid, + unsigned long start, unsigned long end); +#endif /* !__ASSEMBLY__ */ + +#define flush_tlb_all() \ +do { \ + preempt_disable(); \ + __flush_tlb_all(); \ + preempt_enable(); \ +} while(0) + +#define flush_tlb_mm(mm) \ +do { \ + preempt_disable(); \ + __flush_tlb_mm((mm)->context.id); \ + preempt_enable(); \ +} while(0) + +#define flush_tlb_range(vma,start,end) \ +do { \ + preempt_disable(); \ + __flush_tlb_range((vma)->vm_mm->context.id, start, end); \ + preempt_enable(); \ +} while(0) + +#define flush_tlb_page(vma,addr) \ +do { \ + preempt_disable(); \ + __flush_tlb_page((vma)->vm_mm->context.id, addr); \ + preempt_enable(); \ +} while(0) + + +#define __flush_tlb_global() flush_tlb_all() +#define flush_tlb() flush_tlb_all() +#define flush_tlb_kernel_range(start, end) flush_tlb_all() + +#else + +#define flush_tlb() BUG() +#define flush_tlb_all() BUG() +#define flush_tlb_mm(mm) BUG() +#define flush_tlb_page(vma,addr) BUG() +#define flush_tlb_range(mm,start,end) BUG() +#define flush_tlb_kernel_range(start, end) BUG() + +#endif + + +#endif /* _ASM_TLBFLUSH_H */ diff --git a/arch/frv/include/asm/topology.h b/arch/frv/include/asm/topology.h new file mode 100644 index 0000000..9427243 --- /dev/null +++ b/arch/frv/include/asm/topology.h @@ -0,0 +1,12 @@ +#ifndef _ASM_TOPOLOGY_H +#define _ASM_TOPOLOGY_H + +#ifdef CONFIG_NUMA + +#error NUMA not supported yet + +#endif /* CONFIG_NUMA */ + +#include <asm-generic/topology.h> + +#endif /* _ASM_TOPOLOGY_H */ diff --git a/arch/frv/include/asm/types.h b/arch/frv/include/asm/types.h new file mode 100644 index 0000000..613bf1e --- /dev/null +++ b/arch/frv/include/asm/types.h @@ -0,0 +1,40 @@ +/* types.h: FRV types + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_TYPES_H +#define _ASM_TYPES_H + +#include <asm-generic/int-ll64.h> + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +#endif /* __ASSEMBLY__ */ + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#define BITS_PER_LONG 32 + +#ifndef __ASSEMBLY__ + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_TYPES_H */ diff --git a/arch/frv/include/asm/uaccess.h b/arch/frv/include/asm/uaccess.h new file mode 100644 index 0000000..53650c9 --- /dev/null +++ b/arch/frv/include/asm/uaccess.h @@ -0,0 +1,321 @@ +/* uaccess.h: userspace accessor functions + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_UACCESS_H +#define _ASM_UACCESS_H + +/* + * User space memory access functions + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/segment.h> +#include <asm/sections.h> + +#define HAVE_ARCH_UNMAPPED_AREA /* we decide where to put mmaps */ + +#define __ptr(x) ((unsigned long __force *)(x)) + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define __addr_ok(addr) ((unsigned long)(addr) < get_addr_limit()) + +/* + * check that a range of addresses falls within the current address limit + */ +static inline int ___range_ok(unsigned long addr, unsigned long size) +{ +#ifdef CONFIG_MMU + int flag = -EFAULT, tmp; + + asm volatile ( + " addcc %3,%2,%1,icc0 \n" /* set C-flag if addr+size>4GB */ + " subcc.p %1,%4,gr0,icc1 \n" /* jump if addr+size>limit */ + " bc icc0,#0,0f \n" + " bhi icc1,#0,0f \n" + " setlos #0,%0 \n" /* mark okay */ + "0: \n" + : "=r"(flag), "=&r"(tmp) + : "r"(addr), "r"(size), "r"(get_addr_limit()), "0"(flag) + ); + + return flag; + +#else + + if (addr < memory_start || + addr > memory_end || + size > memory_end - memory_start || + addr + size > memory_end) + return -EFAULT; + + return 0; +#endif +} + +#define __range_ok(addr,size) ___range_ok((unsigned long) (addr), (unsigned long) (size)) + +#define access_ok(type,addr,size) (__range_ok((void __user *)(addr), (size)) == 0) +#define __access_ok(addr,size) (__range_ok((addr), (size)) == 0) + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ +#define __put_user(x, ptr) \ +({ \ + int __pu_err = 0; \ + \ + typeof(*(ptr)) __pu_val = (x); \ + __chk_user_ptr(ptr); \ + \ + switch (sizeof (*(ptr))) { \ + case 1: \ + __put_user_asm(__pu_err, __pu_val, ptr, "b", "r"); \ + break; \ + case 2: \ + __put_user_asm(__pu_err, __pu_val, ptr, "h", "r"); \ + break; \ + case 4: \ + __put_user_asm(__pu_err, __pu_val, ptr, "", "r"); \ + break; \ + case 8: \ + __put_user_asm(__pu_err, __pu_val, ptr, "d", "e"); \ + break; \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ +}) + +#define put_user(x, ptr) \ +({ \ + typeof(*(ptr)) __user *_p = (ptr); \ + int _e; \ + \ + _e = __range_ok(_p, sizeof(*_p)); \ + if (_e == 0) \ + _e = __put_user((x), _p); \ + _e; \ +}) + +extern int __put_user_bad(void); + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ + +#ifdef CONFIG_MMU + +#define __put_user_asm(err,x,ptr,dsize,constraint) \ +do { \ + asm volatile("1: st"dsize"%I1 %2,%M1 \n" \ + "2: \n" \ + ".subsection 2 \n" \ + "3: setlos %3,%0 \n" \ + " bra 2b \n" \ + ".previous \n" \ + ".section __ex_table,\"a\" \n" \ + " .balign 8 \n" \ + " .long 1b,3b \n" \ + ".previous" \ + : "=r" (err) \ + : "m" (*__ptr(ptr)), constraint (x), "i"(-EFAULT), "0"(err) \ + : "memory"); \ +} while (0) + +#else + +#define __put_user_asm(err,x,ptr,bwl,con) \ +do { \ + asm(" st"bwl"%I0 %1,%M0 \n" \ + " membar \n" \ + : \ + : "m" (*__ptr(ptr)), con (x) \ + : "memory"); \ +} while (0) + +#endif + +/*****************************************************************************/ +/* + * + */ +#define __get_user(x, ptr) \ +({ \ + int __gu_err = 0; \ + __chk_user_ptr(ptr); \ + \ + switch (sizeof(*(ptr))) { \ + case 1: { \ + unsigned char __gu_val; \ + __get_user_asm(__gu_err, __gu_val, ptr, "ub", "=r"); \ + (x) = *(__force __typeof__(*(ptr)) *) &__gu_val; \ + break; \ + } \ + case 2: { \ + unsigned short __gu_val; \ + __get_user_asm(__gu_err, __gu_val, ptr, "uh", "=r"); \ + (x) = *(__force __typeof__(*(ptr)) *) &__gu_val; \ + break; \ + } \ + case 4: { \ + unsigned int __gu_val; \ + __get_user_asm(__gu_err, __gu_val, ptr, "", "=r"); \ + (x) = *(__force __typeof__(*(ptr)) *) &__gu_val; \ + break; \ + } \ + case 8: { \ + unsigned long long __gu_val; \ + __get_user_asm(__gu_err, __gu_val, ptr, "d", "=e"); \ + (x) = *(__force __typeof__(*(ptr)) *) &__gu_val; \ + break; \ + } \ + default: \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + __gu_err; \ +}) + +#define get_user(x, ptr) \ +({ \ + const typeof(*(ptr)) __user *_p = (ptr);\ + int _e; \ + \ + _e = __range_ok(_p, sizeof(*_p)); \ + if (likely(_e == 0)) \ + _e = __get_user((x), _p); \ + else \ + (x) = (typeof(x)) 0; \ + _e; \ +}) + +extern int __get_user_bad(void); + +#ifdef CONFIG_MMU + +#define __get_user_asm(err,x,ptr,dtype,constraint) \ +do { \ + asm("1: ld"dtype"%I2 %M2,%1 \n" \ + "2: \n" \ + ".subsection 2 \n" \ + "3: setlos %3,%0 \n" \ + " setlos #0,%1 \n" \ + " bra 2b \n" \ + ".previous \n" \ + ".section __ex_table,\"a\" \n" \ + " .balign 8 \n" \ + " .long 1b,3b \n" \ + ".previous" \ + : "=r" (err), constraint (x) \ + : "m" (*__ptr(ptr)), "i"(-EFAULT), "0"(err) \ + ); \ +} while(0) + +#else + +#define __get_user_asm(err,x,ptr,bwl,con) \ + asm(" ld"bwl"%I1 %M1,%0 \n" \ + " membar \n" \ + : con(x) \ + : "m" (*__ptr(ptr))) + +#endif + +/*****************************************************************************/ +/* + * + */ +#define ____force(x) (__force void *)(void __user *)(x) +#ifdef CONFIG_MMU +extern long __memset_user(void *dst, unsigned long count); +extern long __memcpy_user(void *dst, const void *src, unsigned long count); + +#define clear_user(dst,count) __memset_user(____force(dst), (count)) +#define __copy_from_user_inatomic(to, from, n) __memcpy_user((to), ____force(from), (n)) +#define __copy_to_user_inatomic(to, from, n) __memcpy_user(____force(to), (from), (n)) + +#else + +#define clear_user(dst,count) (memset(____force(dst), 0, (count)), 0) +#define __copy_from_user_inatomic(to, from, n) (memcpy((to), ____force(from), (n)), 0) +#define __copy_to_user_inatomic(to, from, n) (memcpy(____force(to), (from), (n)), 0) + +#endif + +#define __clear_user clear_user + +static inline unsigned long __must_check +__copy_to_user(void __user *to, const void *from, unsigned long n) +{ + might_sleep(); + return __copy_to_user_inatomic(to, from, n); +} + +static inline unsigned long +__copy_from_user(void *to, const void __user *from, unsigned long n) +{ + might_sleep(); + return __copy_from_user_inatomic(to, from, n); +} + +static inline long copy_from_user(void *to, const void __user *from, unsigned long n) +{ + unsigned long ret = n; + + if (likely(__access_ok(from, n))) + ret = __copy_from_user(to, from, n); + + if (unlikely(ret != 0)) + memset(to + (n - ret), 0, ret); + + return ret; +} + +static inline long copy_to_user(void __user *to, const void *from, unsigned long n) +{ + return likely(__access_ok(to, n)) ? __copy_to_user(to, from, n) : n; +} + +extern long strncpy_from_user(char *dst, const char __user *src, long count); +extern long strnlen_user(const char __user *src, long count); + +#define strlen_user(str) strnlen_user(str, 32767) + +extern unsigned long search_exception_table(unsigned long addr); + +#endif /* _ASM_UACCESS_H */ diff --git a/arch/frv/include/asm/ucontext.h b/arch/frv/include/asm/ucontext.h new file mode 100644 index 0000000..8d8c0c9 --- /dev/null +++ b/arch/frv/include/asm/ucontext.h @@ -0,0 +1,12 @@ +#ifndef _ASM_UCONTEXT_H +#define _ASM_UCONTEXT_H + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif diff --git a/arch/frv/include/asm/unaligned.h b/arch/frv/include/asm/unaligned.h new file mode 100644 index 0000000..6c61c05 --- /dev/null +++ b/arch/frv/include/asm/unaligned.h @@ -0,0 +1,22 @@ +/* unaligned.h: unaligned access handler + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_UNALIGNED_H +#define _ASM_UNALIGNED_H + +#include <linux/unaligned/le_byteshift.h> +#include <linux/unaligned/be_struct.h> +#include <linux/unaligned/generic.h> + +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be + +#endif /* _ASM_UNALIGNED_H */ diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h new file mode 100644 index 0000000..edcfaf5 --- /dev/null +++ b/arch/frv/include/asm/unistd.h @@ -0,0 +1,382 @@ +#ifndef _ASM_UNISTD_H_ +#define _ASM_UNISTD_H_ + +/* + * This file contains the system call numbers. + */ + +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_lchown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +// #define __NR_oldolduname /* 59 */ obsolete +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +// #define __NR_mmap 90 /* obsolete - not implemented */ +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +// #define __NR_profil /* 98 */ obsolete +#define __NR_statfs 99 +#define __NR_fstatfs 100 +// #define __NR_ioperm /* 101 */ not supported +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +// #define __NR_olduname /* 109 */ obsolete +// #define __NR_iopl /* 110 */ not supported +#define __NR_vhangup 111 +// #define __NR_idle /* 112 */ Obsolete +// #define __NR_vm86old /* 113 */ not supported +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +// #define __NR_modify_ldt /* 123 */ not supported +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +// #define __NR_vm86 /* 166 */ not supported +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_chown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_lchown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_chown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_mincore 218 +#define __NR_madvise 219 + +#define __NR_getdents64 220 +#define __NR_fcntl64 221 +#define __NR_security 223 /* syscall for security modules */ +#define __NR_gettid 224 +#define __NR_readahead 225 +#define __NR_setxattr 226 +#define __NR_lsetxattr 227 +#define __NR_fsetxattr 228 +#define __NR_getxattr 229 +#define __NR_lgetxattr 230 +#define __NR_fgetxattr 231 +#define __NR_listxattr 232 +#define __NR_llistxattr 233 +#define __NR_flistxattr 234 +#define __NR_removexattr 235 +#define __NR_lremovexattr 236 +#define __NR_fremovexattr 237 +#define __NR_tkill 238 +#define __NR_sendfile64 239 +#define __NR_futex 240 +#define __NR_sched_setaffinity 241 +#define __NR_sched_getaffinity 242 +#define __NR_set_thread_area 243 +#define __NR_get_thread_area 244 +#define __NR_io_setup 245 +#define __NR_io_destroy 246 +#define __NR_io_getevents 247 +#define __NR_io_submit 248 +#define __NR_io_cancel 249 +#define __NR_fadvise64 250 + +#define __NR_exit_group 252 +#define __NR_lookup_dcookie 253 +#define __NR_epoll_create 254 +#define __NR_epoll_ctl 255 +#define __NR_epoll_wait 256 +#define __NR_remap_file_pages 257 +#define __NR_set_tid_address 258 +#define __NR_timer_create 259 +#define __NR_timer_settime (__NR_timer_create+1) +#define __NR_timer_gettime (__NR_timer_create+2) +#define __NR_timer_getoverrun (__NR_timer_create+3) +#define __NR_timer_delete (__NR_timer_create+4) +#define __NR_clock_settime (__NR_timer_create+5) +#define __NR_clock_gettime (__NR_timer_create+6) +#define __NR_clock_getres (__NR_timer_create+7) +#define __NR_clock_nanosleep (__NR_timer_create+8) +#define __NR_statfs64 268 +#define __NR_fstatfs64 269 +#define __NR_tgkill 270 +#define __NR_utimes 271 +#define __NR_fadvise64_64 272 +#define __NR_vserver 273 +#define __NR_mbind 274 +#define __NR_get_mempolicy 275 +#define __NR_set_mempolicy 276 +#define __NR_mq_open 277 +#define __NR_mq_unlink (__NR_mq_open+1) +#define __NR_mq_timedsend (__NR_mq_open+2) +#define __NR_mq_timedreceive (__NR_mq_open+3) +#define __NR_mq_notify (__NR_mq_open+4) +#define __NR_mq_getsetattr (__NR_mq_open+5) +#define __NR_kexec_load 283 +#define __NR_waitid 284 +/* #define __NR_sys_setaltroot 285 */ +#define __NR_add_key 286 +#define __NR_request_key 287 +#define __NR_keyctl 288 +#define __NR_ioprio_set 289 +#define __NR_ioprio_get 290 +#define __NR_inotify_init 291 +#define __NR_inotify_add_watch 292 +#define __NR_inotify_rm_watch 293 +#define __NR_migrate_pages 294 +#define __NR_openat 295 +#define __NR_mkdirat 296 +#define __NR_mknodat 297 +#define __NR_fchownat 298 +#define __NR_futimesat 299 +#define __NR_fstatat64 300 +#define __NR_unlinkat 301 +#define __NR_renameat 302 +#define __NR_linkat 303 +#define __NR_symlinkat 304 +#define __NR_readlinkat 305 +#define __NR_fchmodat 306 +#define __NR_faccessat 307 +#define __NR_pselect6 308 +#define __NR_ppoll 309 +#define __NR_unshare 310 +#define __NR_set_robust_list 311 +#define __NR_get_robust_list 312 +#define __NR_splice 313 +#define __NR_sync_file_range 314 +#define __NR_tee 315 +#define __NR_vmsplice 316 +#define __NR_move_pages 317 +#define __NR_getcpu 318 +#define __NR_epoll_pwait 319 +#define __NR_utimensat 320 +#define __NR_signalfd 321 +#define __NR_timerfd_create 322 +#define __NR_eventfd 323 +#define __NR_fallocate 324 +#define __NR_timerfd_settime 325 +#define __NR_timerfd_gettime 326 +#define __NR_signalfd4 327 +#define __NR_eventfd2 328 +#define __NR_epoll_create1 329 +#define __NR_dup3 330 +#define __NR_pipe2 331 +#define __NR_inotify_init1 332 + +#ifdef __KERNEL__ + +#define NR_syscalls 333 + +#define __ARCH_WANT_IPC_PARSE_VERSION +/* #define __ARCH_WANT_OLD_READDIR */ +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +/* #define __ARCH_WANT_SYS_GETHOSTNAME */ +#define __ARCH_WANT_SYS_PAUSE +/* #define __ARCH_WANT_SYS_SGETMASK */ +/* #define __ARCH_WANT_SYS_SIGNAL */ +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +/* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */ +#define __ARCH_WANT_SYS_OLDUMOUNT +/* #define __ARCH_WANT_SYS_SIGPENDING */ +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#ifndef cond_syscall +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") +#endif + +#endif /* __KERNEL__ */ +#endif /* _ASM_UNISTD_H_ */ diff --git a/arch/frv/include/asm/user.h b/arch/frv/include/asm/user.h new file mode 100644 index 0000000..82fa8fa --- /dev/null +++ b/arch/frv/include/asm/user.h @@ -0,0 +1,80 @@ +/* user.h: FR-V core file format stuff + * + * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_USER_H +#define _ASM_USER_H + +#include <asm/page.h> +#include <asm/registers.h> + +/* Core file format: The core file is written in such a way that gdb + * can understand it and provide useful information to the user (under + * linux we use the 'trad-core' bfd). There are quite a number of + * obstacles to being able to view the contents of the floating point + * registers, and until these are solved you will not be able to view + * the contents of them. Actually, you can read in the core file and + * look at the contents of the user struct to find out what the + * floating point registers contain. + * + * The actual file contents are as follows: + * UPAGE: + * 1 page consisting of a user struct that tells gdb what is present + * in the file. Directly after this is a copy of the task_struct, + * which is currently not used by gdb, but it may come in useful at + * some point. All of the registers are stored as part of the + * upage. The upage should always be only one page. + * + * DATA: + * The data area is stored. We use current->end_text to + * current->brk to pick up all of the user variables, plus any + * memory that may have been malloced. No attempt is made to + * determine if a page is demand-zero or if a page is totally + * unused, we just cover the entire range. All of the addresses are + * rounded in such a way that an integral number of pages is + * written. + * + * STACK: + * We need the stack information in order to get a meaningful + * backtrace. We need to write the data from (esp) to + * current->start_stack, so we round each of these off in order to + * be able to write an integer number of pages. The minimum core + * file size is 3 pages, or 12288 bytes. + */ + +/* When the kernel dumps core, it starts by dumping the user struct - + * this will be used by gdb to figure out where the data and stack segments + * are within the file, and what virtual addresses to use. + */ +struct user { + /* We start with the registers, to mimic the way that "memory" is returned + * from the ptrace(3,...) function. */ + struct user_context regs; + + /* The rest of this junk is to help gdb figure out what goes where */ + unsigned long u_tsize; /* Text segment size (pages). */ + unsigned long u_dsize; /* Data segment size (pages). */ + unsigned long u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + * This is actually the bottom of the stack, + * the top of the stack is always found in the + * esp register. */ + long int signal; /* Signal that caused the core dump. */ + + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ +}; + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif diff --git a/arch/frv/include/asm/vga.h b/arch/frv/include/asm/vga.h new file mode 100644 index 0000000..a702c80 --- /dev/null +++ b/arch/frv/include/asm/vga.h @@ -0,0 +1,17 @@ +/* vga.h: VGA register stuff + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_VGA_H +#define _ASM_VGA_H + + + +#endif /* _ASM_VGA_H */ diff --git a/arch/frv/include/asm/virtconvert.h b/arch/frv/include/asm/virtconvert.h new file mode 100644 index 0000000..59788fa --- /dev/null +++ b/arch/frv/include/asm/virtconvert.h @@ -0,0 +1,41 @@ +/* virtconvert.h: virtual/physical/page address convertion + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _ASM_VIRTCONVERT_H +#define _ASM_VIRTCONVERT_H + +/* + * Macros used for converting between virtual and physical mappings. + */ + +#ifdef __KERNEL__ + +#include <asm/setup.h> + +#ifdef CONFIG_MMU + +#define phys_to_virt(vaddr) ((void *) ((unsigned long)(vaddr) + PAGE_OFFSET)) +#define virt_to_phys(vaddr) ((unsigned long) (vaddr) - PAGE_OFFSET) + +#else + +#define phys_to_virt(vaddr) ((void *) (vaddr)) +#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) + +#endif + +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT)) +#define page_to_phys(page) virt_to_phys((void *)__page_address(page)) + +#endif +#endif diff --git a/arch/frv/include/asm/xor.h b/arch/frv/include/asm/xor.h new file mode 100644 index 0000000..c82eb12 --- /dev/null +++ b/arch/frv/include/asm/xor.h @@ -0,0 +1 @@ +#include <asm-generic/xor.h> diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index 9015979..10a9eb0 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h @@ -308,11 +308,13 @@ #define __NR_dup3 1316 #define __NR_pipe2 1317 #define __NR_inotify_init1 1318 +#define __NR_preadv 1319 +#define __NR_pwritev 1320 #ifdef __KERNEL__ -#define NR_syscalls 295 /* length of syscall table */ +#define NR_syscalls 297 /* length of syscall table */ /* * The following defines stop scripts/checksyscalls.sh from complaining about diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 8dc6966..7bebac0 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1803,6 +1803,8 @@ sys_call_table: data8 sys_dup3 data8 sys_pipe2 data8 sys_inotify_init1 + data8 sys_preadv + data8 sys_pwritev // 1320 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c index 573f02c..285aae8 100644 --- a/arch/ia64/kernel/pci-swiotlb.c +++ b/arch/ia64/kernel/pci-swiotlb.c @@ -16,7 +16,7 @@ EXPORT_SYMBOL(swiotlb); static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) { - if (dev->coherent_dma_mask != DMA_64BIT_MASK) + if (dev->coherent_dma_mask != DMA_BIT_MASK(64)) gfp |= GFP_DMA; return swiotlb_alloc_coherent(dev, size, dma_handle, gfp); } diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig new file mode 100644 index 0000000..8cc312b --- /dev/null +++ b/arch/microblaze/Kconfig @@ -0,0 +1,141 @@ +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. + +mainmenu "Linux/Microblaze Kernel Configuration" + +config MICROBLAZE + def_bool y + select HAVE_LMB + +config SWAP + def_bool n + +config RWSEM_GENERIC_SPINLOCK + def_bool y + +config RWSEM_XCHGADD_ALGORITHM + bool + +config ARCH_HAS_ILOG2_U32 + def_bool n + +config ARCH_HAS_ILOG2_U64 + def_bool n + +config GENERIC_FIND_NEXT_BIT + def_bool y + +config GENERIC_HWEIGHT + def_bool y + +config GENERIC_HARDIRQS + def_bool y + +config GENERIC_IRQ_PROBE + def_bool y + +config GENERIC_CALIBRATE_DELAY + def_bool y + +config GENERIC_TIME + def_bool y + +config GENERIC_TIME_VSYSCALL + def_bool n + +config GENERIC_CLOCKEVENTS + def_bool y + +config GENERIC_HARDIRQS_NO__DO_IRQ + def_bool y + +config PCI + depends on !MMU + def_bool n + +config NO_DMA + depends on !MMU + def_bool n + +source "init/Kconfig" + +source "kernel/Kconfig.freezer" + +source "arch/microblaze/platform/Kconfig.platform" + +menu "Processor type and features" + +source kernel/time/Kconfig + +source "kernel/Kconfig.preempt" + +source "kernel/Kconfig.hz" + +config MMU + def_bool n + +config NO_MMU + bool + depends on !MMU + default y + +comment "Boot options" + +config CMDLINE_BOOL + bool "Default bootloader kernel arguments" + +config CMDLINE + string "Default kernel command string" + depends on CMDLINE_BOOL + default "console=ttyUL0,115200" + help + On some architectures there is currently no way for the boot loader + to pass arguments to the kernel. For these architectures, you should + supply some command-line options at build time by entering them + here. + +config CMDLINE_FORCE + bool "Force default kernel command string" + depends on CMDLINE_BOOL + default n + help + Set this to have arguments from the default kernel command string + override those passed by the boot loader. + +config OF + def_bool y + +config OF_DEVICE + def_bool y + +config PROC_DEVICETREE + bool "Support for device tree in /proc" + depends on PROC_FS + help + This option adds a device-tree directory under /proc which contains + an image of the device tree that the kernel copies from Open + Firmware or other boot firmware. If unsure, say Y here. + +endmenu + +source "mm/Kconfig" + +menu "Exectuable file formats" + +source "fs/Kconfig.binfmt" + +endmenu + +source "net/Kconfig" + +source "drivers/Kconfig" + +source "fs/Kconfig" + +source "arch/microblaze/Kconfig.debug" + +source "security/Kconfig" + +source "crypto/Kconfig" + +source "lib/Kconfig" diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug new file mode 100644 index 0000000..242cd35 --- /dev/null +++ b/arch/microblaze/Kconfig.debug @@ -0,0 +1,26 @@ +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. + +menu "Kernel hacking" + +source "lib/Kconfig.debug" + +config EARLY_PRINTK + bool "Early printk function for kernel" + default n + help + This option turns on/off early printk messages to console. + First Uartlite node is taken. + +config HEART_BEAT + bool "Heart beat function for kernel" + default n + help + This option turns on/off heart beat kernel functionality. + First GPIO node is taken. + +config DEBUG_BOOTMEM + depends on DEBUG_KERNEL + bool "Debug BOOTMEM initialization" + +endmenu diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile new file mode 100644 index 0000000..0dcbb98 --- /dev/null +++ b/arch/microblaze/Makefile @@ -0,0 +1,69 @@ +UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\" + +# What CPU vesion are we building for, and crack it open +# as major.minor.rev +CPU_VER=$(subst ",,$(CONFIG_XILINX_MICROBLAZE0_HW_VER) ) +CPU_MAJOR=$(shell echo $(CPU_VER) | cut -d '.' -f 1) +CPU_MINOR=$(shell echo $(CPU_VER) | cut -d '.' -f 2) +CPU_REV=$(shell echo $(CPU_VER) | cut -d '.' -f 3) + +export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV + +# Use cpu-related CONFIG_ vars to set compile options. + +# Work out HW multipler support. This is icky. +# 1. Spartan2 has no HW multiplers. +# 2. MicroBlaze v3.x always uses them, except in Spartan 2 +# 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings +ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY))) + ifeq ($(CPU_MAJOR),3) + CPUFLAGS-1 += -mno-xl-soft-mul + else + # USE_HW_MUL can be 0, 1, or 2, defining a heirarchy of HW Mul support. + CPUFLAGS-$(subst 1,,$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)) += -mxl-multiply-high + CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) += -mno-xl-soft-mul + endif +endif +CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div +CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift +CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP) += -mxl-pattern-compare + +CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER)) + +# The various CONFIG_XILINX cpu features options are integers 0/1/2... +# rather than bools y/n +CFLAGS += $(CPUFLAGS-1) +CFLAGS += $(CPUFLAGS-2) + +# r31 holds current when in kernel mode +CFLAGS += -ffixed-r31 + +LDFLAGS_BLOB := --format binary --oformat elf32-microblaze + +LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) + +head-y := arch/microblaze/kernel/head.o +libs-y += arch/microblaze/lib/ $(LIBGCC) +core-y += arch/microblaze/kernel/ arch/microblaze/mm/ \ + arch/microblaze/platform/ + +boot := arch/$(ARCH)/boot + +# defines filename extension depending memory management type +ifeq ($(CONFIG_MMU),) +MMUEXT := -nommu +endif +export MMUEXT + +all: linux.bin + +archclean: + $(Q)$(MAKE) $(clean)=$(boot) + +linux.bin linux.bin.gz: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + +define archhelp + echo '* linux.bin - Create raw binary' + echo ' linux.bin.gz - Create compressed raw binary' +endef diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile new file mode 100644 index 0000000..844edf4 --- /dev/null +++ b/arch/microblaze/boot/Makefile @@ -0,0 +1,17 @@ +# +# arch/microblaze/boot/Makefile +# + +targets := linux.bin linux.bin.gz + +OBJCOPYFLAGS_linux.bin := -O binary + +$(obj)/linux.bin: vmlinux FORCE + $(call if_changed,objcopy) + @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' + +$(obj)/linux.bin.gz: $(obj)/linux.bin FORCE + $(call if_changed,gzip) + @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' + +clean-kernel += linux.bin linux.bin.gz diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig new file mode 100644 index 0000000..beb7ecd --- /dev/null +++ b/arch/microblaze/configs/nommu_defconfig @@ -0,0 +1,804 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.29 +# Tue Mar 24 10:23:20 2009 +# +CONFIG_MICROBLAZE=y +# CONFIG_SWAP is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +# CONFIG_PCI is not set +# CONFIG_NO_DMA is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_AIO=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=1 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# Platform options +# +CONFIG_PLATFORM_GENERIC=y +# CONFIG_SELFMOD is not set +# CONFIG_OPT_LIB_FUNCTION is not set +# CONFIG_ALLOW_EDIT_AUTO is not set +CONFIG_KERNEL_BASE_ADDR=0x90000000 +CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex5" +CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 +CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1 +CONFIG_XILINX_MICROBLAZE0_USE_DIV=1 +CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2 +CONFIG_XILINX_MICROBLAZE0_USE_FPU=2 +CONFIG_XILINX_MICROBLAZE0_HW_VER="7.10.d" + +# +# Processor type and features +# +CONFIG_TICK_ONESHOT=y +# CONFIG_NO_HZ is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +CONFIG_SCHED_HRTICK=y +# CONFIG_MMU is not set +CONFIG_NO_MMU=y + +# +# Boot options +# +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyUL0,115200" +# CONFIG_CMDLINE_FORCE is not set +CONFIG_OF=y +CONFIG_OF_DEVICE=y +CONFIG_PROC_DEVICETREE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y + +# +# Exectuable file formats +# +CONFIG_BINFMT_FLAT=y +# CONFIG_BINFMT_ZFLAT is not set +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_COMPAT_NET_DEV_OPS=y +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_PHONET is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +CONFIG_WIRELESS_OLD_REGULATORY=y +# CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set +# CONFIG_MAC80211 is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_UCLINUX=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +CONFIG_DAB=y + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_SOUND is not set +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set + +# +# Enable Host or Gadget support to see Inventra options +# + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_REGISTER_V4 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_SELFTEST=y +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_DEBUG_LIST=y +CONFIG_DEBUG_SG=y +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y + +# +# Tracers +# +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_EARLY_PRINTK=y +CONFIG_HEART_BEAT=y +# CONFIG_DEBUG_BOOTMEM is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +# CONFIG_CRC32 is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild new file mode 100644 index 0000000..31820df --- /dev/null +++ b/arch/microblaze/include/asm/Kbuild @@ -0,0 +1,26 @@ +include include/asm-generic/Kbuild.asm + +header-y += auxvec.h +header-y += errno.h +header-y += fcntl.h +header-y += ioctl.h +header-y += ioctls.h +header-y += ipcbuf.h +header-y += linkage.h +header-y += msgbuf.h +header-y += poll.h +header-y += resource.h +header-y += sembuf.h +header-y += shmbuf.h +header-y += sigcontext.h +header-y += siginfo.h +header-y += socket.h +header-y += sockios.h +header-y += statfs.h +header-y += stat.h +header-y += termbits.h +header-y += ucontext.h + +unifdef-y += cputable.h +unifdef-y += elf.h +unifdef-y += termios.h diff --git a/arch/microblaze/include/asm/atomic.h b/arch/microblaze/include/asm/atomic.h new file mode 100644 index 0000000..a448d94 --- /dev/null +++ b/arch/microblaze/include/asm/atomic.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_ATOMIC_H +#define _ASM_MICROBLAZE_ATOMIC_H + +#include <linux/types.h> +#include <linux/compiler.h> /* likely */ +#include <asm/system.h> /* local_irq_XXX and friends */ + +#define ATOMIC_INIT(i) { (i) } +#define atomic_read(v) ((v)->counter) +#define atomic_set(v, i) (((v)->counter) = (i)) + +#define atomic_inc(v) (atomic_add_return(1, (v))) +#define atomic_dec(v) (atomic_sub_return(1, (v))) + +#define atomic_add(i, v) (atomic_add_return(i, (v))) +#define atomic_sub(i, v) (atomic_sub_return(i, (v))) + +#define atomic_inc_return(v) (atomic_add_return(1, (v))) +#define atomic_dec_return(v) (atomic_sub_return(1, (v))) + +#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) + +#define atomic_inc_not_zero(v) (atomic_add_unless((v), 1, 0)) + +#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) + +static inline int atomic_cmpxchg(atomic_t *v, int old, int new) +{ + int ret; + unsigned long flags; + + local_irq_save(flags); + ret = v->counter; + if (likely(ret == old)) + v->counter = new; + local_irq_restore(flags); + + return ret; +} + +static inline int atomic_add_unless(atomic_t *v, int a, int u) +{ + int c, old; + + c = atomic_read(v); + while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) + c = old; + return c != u; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long flags; + + local_irq_save(flags); + *addr &= ~mask; + local_irq_restore(flags); +} + +/** + * atomic_add_return - add and return + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v and returns @i + @v + */ +static inline int atomic_add_return(int i, atomic_t *v) +{ + unsigned long flags; + int val; + + local_irq_save(flags); + val = v->counter; + v->counter = val += i; + local_irq_restore(flags); + + return val; +} + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + return atomic_add_return(-i, v); +} + +/* + * Atomically test *v and decrement if it is greater than 0. + * The function returns the old value of *v minus 1. + */ +static inline int atomic_dec_if_positive(atomic_t *v) +{ + unsigned long flags; + int res; + + local_irq_save(flags); + res = v->counter - 1; + if (res >= 0) + v->counter = res; + local_irq_restore(flags); + + return res; +} + +#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + +/* Atomic operations are already serializing */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#include <asm-generic/atomic.h> + +#endif /* _ASM_MICROBLAZE_ATOMIC_H */ diff --git a/arch/microblaze/include/asm/auxvec.h b/arch/microblaze/include/asm/auxvec.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/arch/microblaze/include/asm/auxvec.h @@ -0,0 +1 @@ + diff --git a/arch/microblaze/include/asm/bitops.h b/arch/microblaze/include/asm/bitops.h new file mode 100644 index 0000000..d6df1fd --- /dev/null +++ b/arch/microblaze/include/asm/bitops.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_BITOPS_H +#define _ASM_MICROBLAZE_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +#include <asm/byteorder.h> /* swab32 */ +#include <asm/system.h> /* save_flags */ + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() +#include <asm-generic/bitops.h> +#include <asm-generic/bitops/__fls.h> + +#endif /* _ASM_MICROBLAZE_BITOPS_H */ diff --git a/arch/microblaze/include/asm/bug.h b/arch/microblaze/include/asm/bug.h new file mode 100644 index 0000000..8eb2cdd --- /dev/null +++ b/arch/microblaze/include/asm/bug.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_BUG_H +#define _ASM_MICROBLAZE_BUG_H + +#include <linux/kernel.h> +#include <asm-generic/bug.h> + +#endif /* _ASM_MICROBLAZE_BUG_H */ diff --git a/arch/microblaze/include/asm/bugs.h b/arch/microblaze/include/asm/bugs.h new file mode 100644 index 0000000..f2c6593 --- /dev/null +++ b/arch/microblaze/include/asm/bugs.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_BUGS_H +#define _ASM_MICROBLAZE_BUGS_H + +static inline void check_bugs(void) +{ + /* nothing to do */ +} + +#endif /* _ASM_MICROBLAZE_BUGS_H */ diff --git a/arch/microblaze/include/asm/byteorder.h b/arch/microblaze/include/asm/byteorder.h new file mode 100644 index 0000000..ce9c587 --- /dev/null +++ b/arch/microblaze/include/asm/byteorder.h @@ -0,0 +1,6 @@ +#ifndef _ASM_MICROBLAZE_BYTEORDER_H +#define _ASM_MICROBLAZE_BYTEORDER_H + +#include <linux/byteorder/big_endian.h> + +#endif /* _ASM_MICROBLAZE_BYTEORDER_H */ diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h new file mode 100644 index 0000000..c4c64b4 --- /dev/null +++ b/arch/microblaze/include/asm/cache.h @@ -0,0 +1,45 @@ +/* + * Cache operations + * + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#ifndef _ASM_MICROBLAZE_CACHE_H +#define _ASM_MICROBLAZE_CACHE_H + +#include <asm/registers.h> + +#define L1_CACHE_SHIFT 2 +/* word-granular cache in microblaze */ +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +#define SMP_CACHE_BYTES L1_CACHE_BYTES + +void _enable_icache(void); +void _disable_icache(void); +void _invalidate_icache(unsigned int addr); + +#define __enable_icache() _enable_icache() +#define __disable_icache() _disable_icache() +#define __invalidate_icache(addr) _invalidate_icache(addr) + +void _enable_dcache(void); +void _disable_dcache(void); +void _invalidate_dcache(unsigned int addr); + +#define __enable_dcache() _enable_dcache() +#define __disable_dcache() _disable_dcache() +#define __invalidate_dcache(addr) _invalidate_dcache(addr) + +/* FIXME - I don't think this is right */ +#ifdef CONFIG_XILINX_UNCACHED_SHADOW +#define UNCACHED_SHADOW_MASK (CONFIG_XILINX_ERAM_SIZE) +#endif + +#endif /* _ASM_MICROBLAZE_CACHE_H */ diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h new file mode 100644 index 0000000..3300b78 --- /dev/null +++ b/arch/microblaze/include/asm/cacheflush.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2007 PetaLogix + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * based on v850 version which was + * Copyright (C) 2001,02,03 NEC Electronics Corporation + * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + * + */ + +#ifndef _ASM_MICROBLAZE_CACHEFLUSH_H +#define _ASM_MICROBLAZE_CACHEFLUSH_H + +/* Somebody depends on this; sigh... */ +#include <linux/mm.h> + +/* + * Cache handling functions. + * Microblaze has a write-through data cache, meaning that the data cache + * never needs to be flushed. The only flushing operations that are + * implemented are to invalidate the instruction cache. These are called + * after loading a user application into memory, we must invalidate the + * instruction cache to make sure we don't fetch old, bad code. + */ + +/* FIXME for LL-temac driver */ +#define invalidate_dcache_range(start, end) \ + __invalidate_dcache_range(start, end) + +#define flush_cache_all() __invalidate_cache_all() +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(vma, start, end) __invalidate_cache_all() +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) + +#define flush_dcache_range(start, end) __invalidate_dcache_range(start, end) +#define flush_dcache_page(page) do { } while (0) +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) + +#define flush_icache_range(start, len) __invalidate_icache_range(start, len) +#define flush_icache_page(vma, pg) do { } while (0) + +#define flush_cache_vmap(start, end) do { } while (0) +#define flush_cache_vunmap(start, end) do { } while (0) + +struct page; +struct mm_struct; +struct vm_area_struct; + +/* see arch/microblaze/kernel/cache.c */ +extern void __invalidate_icache_all(void); +extern void __invalidate_icache_range(unsigned long start, unsigned long end); +extern void __invalidate_icache_page(struct vm_area_struct *vma, + struct page *page); +extern void __invalidate_icache_user_range(struct vm_area_struct *vma, + struct page *page, + unsigned long adr, int len); +extern void __invalidate_cache_sigtramp(unsigned long addr); + +extern void __invalidate_dcache_all(void); +extern void __invalidate_dcache_range(unsigned long start, unsigned long end); +extern void __invalidate_dcache_page(struct vm_area_struct *vma, + struct page *page); +extern void __invalidate_dcache_user_range(struct vm_area_struct *vma, + struct page *page, + unsigned long adr, int len); + +extern inline void __invalidate_cache_all(void) +{ + __invalidate_icache_all(); + __invalidate_dcache_all(); +} + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ +do { memcpy((dst), (src), (len)); \ + flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \ +} while (0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy((dst), (src), (len)) + +#endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */ diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h new file mode 100644 index 0000000..92b3076 --- /dev/null +++ b/arch/microblaze/include/asm/checksum.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2008 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_CHECKSUM_H +#define _ASM_MICROBLAZE_CHECKSUM_H + +#include <linux/in6.h> + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + __asm__("add %0, %0, %1\n\t" + "addc %0, %0, %2\n\t" + "addc %0, %0, %3\n\t" + "addc %0, %0, r0\n\t" + : "+&d" (sum) + : "d" (saddr), "d" (daddr), "d" (len + proto)); + + return sum; +} + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +extern __wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +extern __wsum csum_partial_copy(const char *src, char *dst, int len, int sum); + +/* + * the same as csum_partial_copy, but copies from user space. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ +extern __wsum csum_partial_copy_from_user(const char *src, char *dst, + int len, int sum, int *csum_err); + +#define csum_partial_copy_nocheck(src, dst, len, sum) \ + csum_partial_copy((src), (dst), (len), (sum)) + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + */ +extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); + +/* + * Fold a partial checksum + */ +static inline __sum16 csum_fold(unsigned int sum) +{ + sum = (sum & 0xffff) + (sum >> 16); + sum = (sum & 0xffff) + (sum >> 16); + return ~sum; +} + +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +extern __sum16 ip_compute_csum(const unsigned char *buff, int len); + +#endif /* _ASM_MICROBLAZE_CHECKSUM_H */ diff --git a/arch/microblaze/include/asm/clinkage.h b/arch/microblaze/include/asm/clinkage.h new file mode 100644 index 0000000..9e21843 --- /dev/null +++ b/arch/microblaze/include/asm/clinkage.h @@ -0,0 +1 @@ +#include <linux/linkage.h> diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h new file mode 100644 index 0000000..52f28f6 --- /dev/null +++ b/arch/microblaze/include/asm/cpuinfo.h @@ -0,0 +1,102 @@ +/* + * Generic support for queying CPU info + * + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2007 John Williams <jwilliams@itee.uq.edu.au> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#ifndef _ASM_MICROBLAZE_CPUINFO_H +#define _ASM_MICROBLAZE_CPUINFO_H + +#include <asm/prom.h> + +/* CPU Version and FPGA Family code conversion table type */ +struct cpu_ver_key { + const char *s; + const unsigned k; +}; + +extern const struct cpu_ver_key cpu_ver_lookup[]; + +struct family_string_key { + const char *s; + const unsigned k; +}; + +extern const struct family_string_key family_string_lookup[]; + +struct cpuinfo { + /* Core CPU configuration */ + u32 use_instr; + u32 use_mult; + u32 use_fpu; + u32 use_exc; + u32 ver_code; + u32 mmu; + + /* CPU caches */ + u32 use_icache; + u32 icache_tagbits; + u32 icache_write; + u32 icache_line; + u32 icache_size; + unsigned long icache_base; + unsigned long icache_high; + + u32 use_dcache; + u32 dcache_tagbits; + u32 dcache_write; + u32 dcache_line; + u32 dcache_size; + unsigned long dcache_base; + unsigned long dcache_high; + + /* Bus connections */ + u32 use_dopb; + u32 use_iopb; + u32 use_dlmb; + u32 use_ilmb; + u32 num_fsl; + + /* CPU interrupt line info */ + u32 irq_edge; + u32 irq_positive; + + u32 area_optimised; + + /* HW debug support */ + u32 hw_debug; + u32 num_pc_brk; + u32 num_rd_brk; + u32 num_wr_brk; + u32 cpu_clock_freq; /* store real freq of cpu */ + u32 freq_div_hz; /* store freq/HZ */ + + /* FPGA family */ + u32 fpga_family_code; + + /* User define */ + u32 pvr_user1; + u32 pvr_user2; +}; + +extern struct cpuinfo cpuinfo; + +/* fwd declarations of the various CPUinfo populators */ +void setup_cpuinfo(void); + +void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu); +void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu); + +static inline unsigned int fcpu(struct device_node *cpu, char *n) +{ + int *val; + return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0; +} + +#endif /* _ASM_MICROBLAZE_CPUINFO_H */ diff --git a/arch/microblaze/include/asm/cputable.h b/arch/microblaze/include/asm/cputable.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/arch/microblaze/include/asm/cputable.h @@ -0,0 +1 @@ + diff --git a/arch/microblaze/include/asm/cputime.h b/arch/microblaze/include/asm/cputime.h new file mode 100644 index 0000000..6d68ad7 --- /dev/null +++ b/arch/microblaze/include/asm/cputime.h @@ -0,0 +1 @@ +#include <asm-generic/cputime.h> diff --git a/arch/microblaze/include/asm/current.h b/arch/microblaze/include/asm/current.h new file mode 100644 index 0000000..8375ea9 --- /dev/null +++ b/arch/microblaze/include/asm/current.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_CURRENT_H +#define _ASM_MICROBLAZE_CURRENT_H + +# ifndef __ASSEMBLY__ +/* + * Dedicate r31 to keeping the current task pointer + */ +register struct task_struct *current asm("r31"); + +# define get_current() current +# endif /* __ASSEMBLY__ */ + +#endif /* _ASM_MICROBLAZE_CURRENT_H */ diff --git a/arch/microblaze/include/asm/delay.h b/arch/microblaze/include/asm/delay.h new file mode 100644 index 0000000..05b7d39 --- /dev/null +++ b/arch/microblaze/include/asm/delay.h @@ -0,0 +1,72 @@ +/* + * include/asm-microblaze/delay.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Michal Simek + * Copyright (C) 2007 John Williams + * Copyright (C) 2006 Atmark Techno, Inc. + */ + +#ifndef _ASM_MICROBLAZE_DELAY_H +#define _ASM_MICROBLAZE_DELAY_H + +extern inline void __delay(unsigned long loops) +{ + asm volatile ("# __delay \n\t" \ + "1: addi %0, %0, -1\t\n" \ + "bneid %0, 1b \t\n" \ + "nop \t\n" + : "=r" (loops) + : "0" (loops)); +} + +/* + * Note that 19 * 226 == 4294 ==~ 2^32 / 10^6, so + * loops = (4294 * usecs * loops_per_jiffy * HZ) / 2^32. + * + * The mul instruction gives us loops = (a * b) / 2^32. + * We choose a = usecs * 19 * HZ and b = loops_per_jiffy * 226 + * because this lets us support a wide range of HZ and + * loops_per_jiffy values without either a or b overflowing 2^32. + * Thus we need usecs * HZ <= (2^32 - 1) / 19 = 226050910 and + * loops_per_jiffy <= (2^32 - 1) / 226 = 19004280 + * (which corresponds to ~3800 bogomips at HZ = 100). + * -- paulus + */ +#define __MAX_UDELAY (226050910UL/HZ) /* maximum udelay argument */ +#define __MAX_NDELAY (4294967295UL/HZ) /* maximum ndelay argument */ + +extern unsigned long loops_per_jiffy; + +extern inline void __udelay(unsigned int x) +{ + + unsigned long long tmp = + (unsigned long long)x * (unsigned long long)loops_per_jiffy \ + * 226LL; + unsigned loops = tmp >> 32; + +/* + __asm__("mulxuu %0,%1,%2" : "=r" (loops) : + "r" (x), "r" (loops_per_jiffy * 226)); +*/ + __delay(loops); +} + +extern void __bad_udelay(void); /* deliberately undefined */ +extern void __bad_ndelay(void); /* deliberately undefined */ + +#define udelay(n) (__builtin_constant_p(n) ? \ + ((n) > __MAX_UDELAY ? __bad_udelay() : __udelay((n) * (19 * HZ))) : \ + __udelay((n) * (19 * HZ))) + +#define ndelay(n) (__builtin_constant_p(n) ? \ + ((n) > __MAX_NDELAY ? __bad_ndelay() : __udelay((n) * HZ)) : \ + __udelay((n) * HZ)) + +#define muldiv(a, b, c) (((a)*(b))/(c)) + +#endif /* _ASM_MICROBLAZE_DELAY_H */ diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h new file mode 100644 index 0000000..c042830 --- /dev/null +++ b/arch/microblaze/include/asm/device.h @@ -0,0 +1,21 @@ +/* + * Arch specific extensions to struct device + * + * This file is subject to the terms and conditions of the GNU General Public + * License v2. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_DEVICE_H +#define _ASM_MICROBLAZE_DEVICE_H + +struct device_node; + +struct dev_archdata { + /* Optional pointer to an OF device node */ + struct device_node *of_node; +}; + +#endif /* _ASM_MICROBLAZE_DEVICE_H */ + + diff --git a/arch/microblaze/include/asm/div64.h b/arch/microblaze/include/asm/div64.h new file mode 100644 index 0000000..6cd978c --- /dev/null +++ b/arch/microblaze/include/asm/div64.h @@ -0,0 +1 @@ +#include <asm-generic/div64.h> diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h new file mode 100644 index 0000000..1733625 --- /dev/null +++ b/arch/microblaze/include/asm/dma-mapping.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H +#define _ASM_MICROBLAZE_DMA_MAPPING_H + +#include <asm/cacheflush.h> +#include <linux/io.h> +#include <linux/bug.h> + +struct scatterlist; + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) + +/* FIXME */ +static inline int +dma_supported(struct device *dev, u64 mask) +{ + return 1; +} + +static inline dma_addr_t +dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + BUG(); + return 0; +} + +static inline void +dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline int +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction) +{ + BUG(); + return 0; +} + +static inline void +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline void +dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline void +dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + BUG(); +} + +static inline void +dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline void +dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} + +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, int flag) +{ + return NULL; /* consistent_alloc(flag, size, dma_handle); */ +} + +static inline void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + BUG(); +} + +static inline dma_addr_t +dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + + return virt_to_bus(ptr); +} + +static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, + size_t size, + enum dma_data_direction direction) +{ + switch (direction) { + case DMA_FROM_DEVICE: + flush_dcache_range((unsigned)dma_addr, + (unsigned)dma_addr + size); + /* Fall through */ + case DMA_TO_DEVICE: + break; + default: + BUG(); + } +} + +#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */ diff --git a/arch/microblaze/include/asm/dma.h b/arch/microblaze/include/asm/dma.h new file mode 100644 index 0000000..0967fa0 --- /dev/null +++ b/arch/microblaze/include/asm/dma.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_DMA_H +#define _ASM_MICROBLAZE_DMA_H + +/* we don't have dma address limit. define it as zero to be + * unlimited. */ +#define MAX_DMA_ADDRESS (0) + +#endif /* _ASM_MICROBLAZE_DMA_H */ diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h new file mode 100644 index 0000000..81337f2 --- /dev/null +++ b/arch/microblaze/include/asm/elf.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_ELF_H +#define _ASM_MICROBLAZE_ELF_H + +/* + * Note there is no "official" ELF designation for Microblaze. + * I've snaffled the value from the microblaze binutils source code + * /binutils/microblaze/include/elf/microblaze.h + */ +#define EM_XILINX_MICROBLAZE 0xbaab +#define ELF_ARCH EM_XILINX_MICROBLAZE + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x)->e_machine == EM_XILINX_MICROBLAZE) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 + +#endif /* _ASM_MICROBLAZE_ELF_H */ diff --git a/arch/microblaze/include/asm/emergency-restart.h b/arch/microblaze/include/asm/emergency-restart.h new file mode 100644 index 0000000..3711bd9 --- /dev/null +++ b/arch/microblaze/include/asm/emergency-restart.h @@ -0,0 +1 @@ +#include <asm-generic/emergency-restart.h> diff --git a/arch/microblaze/include/asm/entry.h b/arch/microblaze/include/asm/entry.h new file mode 100644 index 0000000..7f57e42 --- /dev/null +++ b/arch/microblaze/include/asm/entry.h @@ -0,0 +1,35 @@ +/* + * Definitions used by low-level trap handlers + * + * Copyright (C) 2008 Michal Simek + * Copyright (C) 2007 - 2008 PetaLogix + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#ifndef _ASM_MICROBLAZE_ENTRY_H +#define _ASM_MICROBLAZE_ENTRY_H + +#include <asm/percpu.h> +#include <asm/ptrace.h> + +/* + * These are per-cpu variables required in entry.S, among other + * places + */ + +#define PER_CPU(var) per_cpu__##var + +# ifndef __ASSEMBLY__ +DECLARE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */ +DECLARE_PER_CPU(unsigned int, KM); /* Kernel/user mode */ +DECLARE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */ +DECLARE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */ +DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ +DECLARE_PER_CPU(unsigned int, SYSCALL_SAVE); /* Saved syscall number */ +# endif /* __ASSEMBLY__ */ + +#endif /* _ASM_MICROBLAZE_ENTRY_H */ diff --git a/arch/microblaze/include/asm/errno.h b/arch/microblaze/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/arch/microblaze/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h new file mode 100644 index 0000000..4cdd215 --- /dev/null +++ b/arch/microblaze/include/asm/exceptions.h @@ -0,0 +1,96 @@ +/* + * Preliminary support for HW exception handing for Microblaze + * + * Copyright (C) 2008 Michal Simek + * Copyright (C) 2008 PetaLogix + * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#ifndef _ASM_MICROBLAZE_EXCEPTIONS_H +#define _ASM_MICROBLAZE_EXCEPTIONS_H + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +/* Macros to enable and disable HW exceptions in the MSR */ +/* Define MSR enable bit for HW exceptions */ +#define HWEX_MSR_BIT (1 << 8) + +#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR +#define __enable_hw_exceptions() \ + __asm__ __volatile__ (" msrset r0, %0; \ + nop;" \ + : \ + : "i" (HWEX_MSR_BIT) \ + : "memory") + +#define __disable_hw_exceptions() \ + __asm__ __volatile__ (" msrclr r0, %0; \ + nop;" \ + : \ + : "i" (HWEX_MSR_BIT) \ + : "memory") +#else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ +#define __enable_hw_exceptions() \ + __asm__ __volatile__ (" \ + mfs r12, rmsr; \ + nop; \ + ori r12, r12, %0; \ + mts rmsr, r12; \ + nop;" \ + : \ + : "i" (HWEX_MSR_BIT) \ + : "memory", "r12") + +#define __disable_hw_exceptions() \ + __asm__ __volatile__ (" \ + mfs r12, rmsr; \ + nop; \ + andi r12, r12, ~%0; \ + mts rmsr, r12; \ + nop;" \ + : \ + : "i" (HWEX_MSR_BIT) \ + : "memory", "r12") +#endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ + +asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, + int fsr, int addr); + +#if defined(CONFIG_XMON) +extern void xmon(struct pt_regs *regs); +extern int xmon_bpt(struct pt_regs *regs); +extern int xmon_sstep(struct pt_regs *regs); +extern int xmon_iabr_match(struct pt_regs *regs); +extern int xmon_dabr_match(struct pt_regs *regs); +extern void (*xmon_fault_handler)(struct pt_regs *regs); + +void (*debugger)(struct pt_regs *regs) = xmon; +int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt; +int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep; +int (*debugger_iabr_match)(struct pt_regs *regs) = xmon_iabr_match; +int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match; +void (*debugger_fault_handler)(struct pt_regs *regs); +#elif defined(CONFIG_KGDB) +void (*debugger)(struct pt_regs *regs); +int (*debugger_bpt)(struct pt_regs *regs); +int (*debugger_sstep)(struct pt_regs *regs); +int (*debugger_iabr_match)(struct pt_regs *regs); +int (*debugger_dabr_match)(struct pt_regs *regs); +void (*debugger_fault_handler)(struct pt_regs *regs); +#else +#define debugger(regs) do { } while (0) +#define debugger_bpt(regs) 0 +#define debugger_sstep(regs) 0 +#define debugger_iabr_match(regs) 0 +#define debugger_dabr_match(regs) 0 +#define debugger_fault_handler ((void (*)(struct pt_regs *))0) +#endif + +#endif /*__ASSEMBLY__ */ +#endif /* __KERNEL__ */ +#endif /* _ASM_MICROBLAZE_EXCEPTIONS_H */ diff --git a/arch/microblaze/include/asm/fcntl.h b/arch/microblaze/include/asm/fcntl.h new file mode 100644 index 0000000..46ab12d --- /dev/null +++ b/arch/microblaze/include/asm/fcntl.h @@ -0,0 +1 @@ +#include <asm-generic/fcntl.h> diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h new file mode 100644 index 0000000..acf0da5 --- /dev/null +++ b/arch/microblaze/include/asm/flat.h @@ -0,0 +1,90 @@ +/* + * uClinux flat-format executables + * + * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#ifndef _ASM_MICROBLAZE_FLAT_H +#define _ASM_MICROBLAZE_FLAT_H + +#include <asm/unaligned.h> + +#define flat_stack_align(sp) /* nothing needed */ +#define flat_argvp_envp_on_stack() 0 +#define flat_old_ram_flag(flags) (flags) +#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) +#define flat_set_persistent(relval, p) 0 + +/* + * Microblaze works a little differently from other arches, because + * of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split + * over two instructions, an 'imm' instruction which provides the top + * 16 bits, then the instruction "proper" which provides the low 16 + * bits. + */ + +/* + * Crack open a symbol reference and extract the address to be + * relocated. rp is a potentially unaligned pointer to the + * reference + */ + +static inline unsigned long +flat_get_addr_from_rp(unsigned long *rp, unsigned long relval, + unsigned long flags, unsigned long *persistent) +{ + unsigned long addr; + (void)flags; + + /* Is it a split 64/32 reference? */ + if (relval & 0x80000000) { + /* Grab the two halves of the reference */ + unsigned long val_hi, val_lo; + + val_hi = get_unaligned(rp); + val_lo = get_unaligned(rp+1); + + /* Crack the address out */ + addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff); + } else { + /* Get the address straight out */ + addr = get_unaligned(rp); + } + + return addr; +} + +/* + * Insert an address into the symbol reference at rp. rp is potentially + * unaligned. + */ + +static inline void +flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval) +{ + /* Is this a split 64/32 reloc? */ + if (relval & 0x80000000) { + /* Get the two "halves" */ + unsigned long val_hi = get_unaligned(rp); + unsigned long val_lo = get_unaligned(rp + 1); + + /* insert the address */ + val_hi = (val_hi & 0xffff0000) | addr >> 16; + val_lo = (val_lo & 0xffff0000) | (addr & 0xffff); + + /* store the two halves back into memory */ + put_unaligned(val_hi, rp); + put_unaligned(val_lo, rp+1); + } else { + /* Put it straight in, no messing around */ + put_unaligned(addr, rp); + } +} + +#define flat_get_relocate_addr(rel) (rel & 0x7fffffff) + +#endif /* _ASM_MICROBLAZE_FLAT_H */ diff --git a/arch/microblaze/include/asm/ftrace.h b/arch/microblaze/include/asm/ftrace.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/arch/microblaze/include/asm/ftrace.h @@ -0,0 +1 @@ + diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h new file mode 100644 index 0000000..0b74582 --- /dev/null +++ b/arch/microblaze/include/asm/futex.h @@ -0,0 +1 @@ +#include <asm-generic/futex.h> diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h new file mode 100644 index 0000000..ea04632 --- /dev/null +++ b/arch/microblaze/include/asm/gpio.h @@ -0,0 +1,56 @@ +/* + * Generic GPIO API implementation for PowerPC. + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <avorontsov@ru.mvista.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __ASM_POWERPC_GPIO_H +#define __ASM_POWERPC_GPIO_H + +#include <linux/errno.h> +#include <asm-generic/gpio.h> + +#ifdef CONFIG_GPIOLIB + +/* + * We don't (yet) implement inlined/rapid versions for on-chip gpios. + * Just call gpiolib. + */ +static inline int gpio_get_value(unsigned int gpio) +{ + return __gpio_get_value(gpio); +} + +static inline void gpio_set_value(unsigned int gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +static inline int gpio_cansleep(unsigned int gpio) +{ + return __gpio_cansleep(gpio); +} + +/* + * Not implemented, yet. + */ +static inline int gpio_to_irq(unsigned int gpio) +{ + return -ENOSYS; +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return -EINVAL; +} + +#endif /* CONFIG_GPIOLIB */ + +#endif /* __ASM_POWERPC_GPIO_H */ diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h new file mode 100644 index 0000000..0f2d6b0 --- /dev/null +++ b/arch/microblaze/include/asm/hardirq.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_HARDIRQ_H +#define _ASM_MICROBLAZE_HARDIRQ_H + +#include <linux/cache.h> +#include <linux/irq.h> +#include <asm/irq.h> +#include <asm/current.h> +#include <linux/ptrace.h> + +/* should be defined in each interrupt controller driver */ +extern unsigned int get_irq(struct pt_regs *regs); + +typedef struct { + unsigned int __softirq_pending; +} ____cacheline_aligned irq_cpustat_t; + +void ack_bad_irq(unsigned int irq); + +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ + +#endif /* _ASM_MICROBLAZE_HARDIRQ_H */ diff --git a/arch/microblaze/include/asm/hw_irq.h b/arch/microblaze/include/asm/hw_irq.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/arch/microblaze/include/asm/hw_irq.h @@ -0,0 +1 @@ + diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h new file mode 100644 index 0000000..8b5853e --- /dev/null +++ b/arch/microblaze/include/asm/io.h @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_IO_H +#define _ASM_MICROBLAZE_IO_H + +#include <asm/byteorder.h> +#include <asm/page.h> +#include <linux/types.h> + +#define IO_SPACE_LIMIT (0xFFFFFFFF) + +static inline unsigned char __raw_readb(const volatile void __iomem *addr) +{ + return *(volatile unsigned char __force *)addr; +} +static inline unsigned short __raw_readw(const volatile void __iomem *addr) +{ + return *(volatile unsigned short __force *)addr; +} +static inline unsigned int __raw_readl(const volatile void __iomem *addr) +{ + return *(volatile unsigned int __force *)addr; +} +static inline unsigned long __raw_readq(const volatile void __iomem *addr) +{ + return *(volatile unsigned long __force *)addr; +} +static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr) +{ + *(volatile unsigned char __force *)addr = v; +} +static inline void __raw_writew(unsigned short v, volatile void __iomem *addr) +{ + *(volatile unsigned short __force *)addr = v; +} +static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) +{ + *(volatile unsigned int __force *)addr = v; +} +static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) +{ + *(volatile unsigned long __force *)addr = v; +} + +/* + * read (readb, readw, readl, readq) and write (writeb, writew, + * writel, writeq) accessors are for PCI and thus littel endian. + * Linux 2.4 for Microblaze had this wrong. + */ +static inline unsigned char readb(const volatile void __iomem *addr) +{ + return *(volatile unsigned char __force *)addr; +} +static inline unsigned short readw(const volatile void __iomem *addr) +{ + return le16_to_cpu(*(volatile unsigned short __force *)addr); +} +static inline unsigned int readl(const volatile void __iomem *addr) +{ + return le32_to_cpu(*(volatile unsigned int __force *)addr); +} +static inline void writeb(unsigned char v, volatile void __iomem *addr) +{ + *(volatile unsigned char __force *)addr = v; +} +static inline void writew(unsigned short v, volatile void __iomem *addr) +{ + *(volatile unsigned short __force *)addr = cpu_to_le16(v); +} +static inline void writel(unsigned int v, volatile void __iomem *addr) +{ + *(volatile unsigned int __force *)addr = cpu_to_le32(v); +} + +/* ioread and iowrite variants. thease are for now same as __raw_ + * variants of accessors. we might check for endianess in the feature + */ +#define ioread8(addr) __raw_readb((u8 *)(addr)) +#define ioread16(addr) __raw_readw((u16 *)(addr)) +#define ioread32(addr) __raw_readl((u32 *)(addr)) +#define iowrite8(v, addr) __raw_writeb((u8)(v), (u8 *)(addr)) +#define iowrite16(v, addr) __raw_writew((u16)(v), (u16 *)(addr)) +#define iowrite32(v, addr) __raw_writel((u32)(v), (u32 *)(addr)) + +/* These are the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl, the "string" versions + * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions + * inb_p/inw_p/... + * The macros don't do byte-swapping. + */ +#define inb(port) readb((u8 *)((port))) +#define outb(val, port) writeb((val), (u8 *)((unsigned long)(port))) +#define inw(port) readw((u16 *)((port))) +#define outw(val, port) writew((val), (u16 *)((unsigned long)(port))) +#define inl(port) readl((u32 *)((port))) +#define outl(val, port) writel((val), (u32 *)((unsigned long)(port))) + +#define inb_p(port) inb((port)) +#define outb_p(val, port) outb((val), (port)) +#define inw_p(port) inw((port)) +#define outw_p(val, port) outw((val), (port)) +#define inl_p(port) inl((port)) +#define outl_p(val, port) outl((val), (port)) + +#define memset_io(a, b, c) memset((void *)(a), (b), (c)) +#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) +#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) + +/** + * virt_to_phys - map virtual addresses to physical + * @address: address to remap + * + * The returned physical address is the physical (CPU) mapping for + * the memory address given. It is only valid to use this function on + * addresses directly mapped or allocated via kmalloc. + * + * This function does not give bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function + */ +static inline unsigned long __iomem virt_to_phys(volatile void *address) +{ + return __pa((unsigned long)address); +} + +#define virt_to_bus virt_to_phys + +/** + * phys_to_virt - map physical address to virtual + * @address: address to remap + * + * The returned virtual address is a current CPU mapping for + * the memory address given. It is only valid to use this function on + * addresses that have a kernel mapping + * + * This function does not handle bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function + */ +static inline void *phys_to_virt(unsigned long address) +{ + return (void *)__va(address); +} + +#define bus_to_virt(a) phys_to_virt(a) + +static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size, + unsigned long flags) +{ + return (void *)address; +} + +#define ioremap(physaddr, size) ((void __iomem *)(unsigned long)(physaddr)) +#define iounmap(addr) ((void)0) +#define ioremap_nocache(physaddr, size) ioremap(physaddr, size) + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +/* + * Big Endian + */ +#define out_be32(a, v) __raw_writel((v), (void __iomem __force *)(a)) +#define out_be16(a, v) __raw_writew((v), (a)) + +#define in_be32(a) __raw_readl((const void __iomem __force *)(a)) +#define in_be16(a) __raw_readw(a) + +/* + * Little endian + */ + +#define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a)); +#define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a)) + +#define in_le32(a) __le32_to_cpu(__raw_readl(a)) +#define in_le16(a) __le16_to_cpu(__raw_readw(a)) + +/* Byte ops */ +#define out_8(a, v) __raw_writeb((v), (a)) +#define in_8(a) __raw_readb(a) + +/* FIXME */ +static inline void __iomem *ioport_map(unsigned long port, unsigned int len) +{ + return (void __iomem *) (port); +} + +static inline void ioport_unmap(void __iomem *addr) +{ + /* Nothing to do */ +} + +#endif /* _ASM_MICROBLAZE_IO_H */ diff --git a/arch/microblaze/include/asm/ioctl.h b/arch/microblaze/include/asm/ioctl.h new file mode 100644 index 0000000..b279fe0 --- /dev/null +++ b/arch/microblaze/include/asm/ioctl.h @@ -0,0 +1 @@ +#include <asm-generic/ioctl.h> diff --git a/arch/microblaze/include/asm/ioctls.h b/arch/microblaze/include/asm/ioctls.h new file mode 100644 index 0000000..03582b2 --- /dev/null +++ b/arch/microblaze/include/asm/ioctls.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_IOCTLS_H +#define _ASM_MICROBLAZE_IOCTLS_H + +#include <linux/ioctl.h> + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +/* Get Pty Number (of pty-mux device) */ +#define TIOCGPTN _IOR('T', 0x30, unsigned int) +#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ + +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +#define FIOQSIZE 0x545E + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* _ASM_MICROBLAZE_IOCTLS_H */ diff --git a/arch/microblaze/include/asm/ipc.h b/arch/microblaze/include/asm/ipc.h new file mode 100644 index 0000000..a46e3d9 --- /dev/null +++ b/arch/microblaze/include/asm/ipc.h @@ -0,0 +1 @@ +#include <asm-generic/ipc.h> diff --git a/arch/microblaze/include/asm/ipcbuf.h b/arch/microblaze/include/asm/ipcbuf.h new file mode 100644 index 0000000..b056fa4 --- /dev/null +++ b/arch/microblaze/include/asm/ipcbuf.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_IPCBUF_H +#define _ASM_MICROBLAZE_IPCBUF_H + +/* + * The user_ipc_perm structure for microblaze architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm { + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* _ASM_MICROBLAZE_IPCBUF_H */ diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h new file mode 100644 index 0000000..db515de --- /dev/null +++ b/arch/microblaze/include/asm/irq.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_IRQ_H +#define _ASM_MICROBLAZE_IRQ_H + +#define NR_IRQS 32 + +#include <linux/interrupt.h> + +extern unsigned int nr_irq; + +#define NO_IRQ (-1) + +static inline int irq_canonicalize(int irq) +{ + return irq; +} + +struct pt_regs; +extern void do_IRQ(struct pt_regs *regs); + +/* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space + * @device: Device node of the device whose interrupt is to be mapped + * @index: Index of the interrupt to map + * + * This function is a wrapper that chains of_irq_map_one() and + * irq_create_of_mapping() to make things easier to callers + */ +struct device_node; +extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index); + +/** FIXME - not implement + * irq_dispose_mapping - Unmap an interrupt + * @virq: linux virq number of the interrupt to unmap + */ +static inline void irq_dispose_mapping(unsigned int virq) +{ + return; +} + +#endif /* _ASM_MICROBLAZE_IRQ_H */ diff --git a/arch/microblaze/include/asm/irq_regs.h b/arch/microblaze/include/asm/irq_regs.h new file mode 100644 index 0000000..3dd9c0b --- /dev/null +++ b/arch/microblaze/include/asm/irq_regs.h @@ -0,0 +1 @@ +#include <asm-generic/irq_regs.h> diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h new file mode 100644 index 0000000..dea6564 --- /dev/null +++ b/arch/microblaze/include/asm/irqflags.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_IRQFLAGS_H +#define _ASM_MICROBLAZE_IRQFLAGS_H + +#include <linux/irqflags.h> + +# if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR + +# define local_irq_save(flags) \ + do { \ + asm volatile ("# local_irq_save \n\t" \ + "msrclr %0, %1 \n\t" \ + "nop \n\t" \ + : "=r"(flags) \ + : "i"(MSR_IE) \ + : "memory"); \ + } while (0) + +# define local_irq_disable() \ + do { \ + asm volatile ("# local_irq_disable \n\t" \ + "msrclr r0, %0 \n\t" \ + "nop \n\t" \ + : \ + : "i"(MSR_IE) \ + : "memory"); \ + } while (0) + +# define local_irq_enable() \ + do { \ + asm volatile ("# local_irq_enable \n\t" \ + "msrset r0, %0 \n\t" \ + "nop \n\t" \ + : \ + : "i"(MSR_IE) \ + : "memory"); \ + } while (0) + +# else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */ + +# define local_irq_save(flags) \ + do { \ + register unsigned tmp; \ + asm volatile ("# local_irq_save \n\t" \ + "mfs %0, rmsr \n\t" \ + "nop \n\t" \ + "andi %1, %0, %2 \n\t" \ + "mts rmsr, %1 \n\t" \ + "nop \n\t" \ + : "=r"(flags), "=r" (tmp) \ + : "i"(~MSR_IE) \ + : "memory"); \ + } while (0) + +# define local_irq_disable() \ + do { \ + register unsigned tmp; \ + asm volatile ("# local_irq_disable \n\t" \ + "mfs %0, rmsr \n\t" \ + "nop \n\t" \ + "andi %0, %0, %1 \n\t" \ + "mts rmsr, %0 \n\t" \ + "nop \n\t" \ + : "=r"(tmp) \ + : "i"(~MSR_IE) \ + : "memory"); \ + } while (0) + +# define local_irq_enable() \ + do { \ + register unsigned tmp; \ + asm volatile ("# local_irq_enable \n\t" \ + "mfs %0, rmsr \n\t" \ + "nop \n\t" \ + "ori %0, %0, %1 \n\t" \ + "mts rmsr, %0 \n\t" \ + "nop \n\t" \ + : "=r"(tmp) \ + : "i"(MSR_IE) \ + : "memory"); \ + } while (0) + +# endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ + +#define local_save_flags(flags) \ + do { \ + asm volatile ("# local_save_flags \n\t" \ + "mfs %0, rmsr \n\t" \ + "nop \n\t" \ + : "=r"(flags) \ + : \ + : "memory"); \ + } while (0) + +#define local_irq_restore(flags) \ + do { \ + asm volatile ("# local_irq_restore \n\t"\ + "mts rmsr, %0 \n\t" \ + "nop \n\t" \ + : \ + : "r"(flags) \ + : "memory"); \ + } while (0) + +static inline int irqs_disabled(void) +{ + unsigned long flags; + + local_save_flags(flags); + return ((flags & MSR_IE) == 0); +} + +#define raw_irqs_disabled irqs_disabled +#define raw_irqs_disabled_flags(flags) ((flags) == 0) + +#endif /* _ASM_MICROBLAZE_IRQFLAGS_H */ diff --git a/arch/microblaze/include/asm/kdebug.h b/arch/microblaze/include/asm/kdebug.h new file mode 100644 index 0000000..6ece1b0 --- /dev/null +++ b/arch/microblaze/include/asm/kdebug.h @@ -0,0 +1 @@ +#include <asm-generic/kdebug.h> diff --git a/arch/microblaze/include/asm/kmap_types.h b/arch/microblaze/include/asm/kmap_types.h new file mode 100644 index 0000000..4d7e222 --- /dev/null +++ b/arch/microblaze/include/asm/kmap_types.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_KMAP_TYPES_H +#define _ASM_MICROBLAZE_KMAP_TYPES_H + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR, +}; + +#endif /* _ASM_MICROBLAZE_KMAP_TYPES_H */ diff --git a/arch/microblaze/include/asm/linkage.h b/arch/microblaze/include/asm/linkage.h new file mode 100644 index 0000000..3a8e36d --- /dev/null +++ b/arch/microblaze/include/asm/linkage.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_LINKAGE_H +#define _ASM_MICROBLAZE_LINKAGE_H + +#define __ALIGN .align 4 +#define __ALIGN_STR ".align 4" + +#endif /* _ASM_MICROBLAZE_LINKAGE_H */ diff --git a/arch/microblaze/include/asm/lmb.h b/arch/microblaze/include/asm/lmb.h new file mode 100644 index 0000000..a0a0a92 --- /dev/null +++ b/arch/microblaze/include/asm/lmb.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2008 Michal Simek <monstr@monstr.eu> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_LMB_H +#define _ASM_MICROBLAZE_LMB_H + +/* LMB limit is OFF */ +#define LMB_REAL_LIMIT 0xFFFFFFFF + +#endif /* _ASM_MICROBLAZE_LMB_H */ + + diff --git a/arch/microblaze/include/asm/local.h b/arch/microblaze/include/asm/local.h new file mode 100644 index 0000000..c11c530 --- /dev/null +++ b/arch/microblaze/include/asm/local.h @@ -0,0 +1 @@ +#include <asm-generic/local.h> diff --git a/arch/microblaze/include/asm/mman.h b/arch/microblaze/include/asm/mman.h new file mode 100644 index 0000000..4914b13 --- /dev/null +++ b/arch/microblaze/include/asm/mman.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_MMAN_H +#define _ASM_MICROBLAZE_MMAN_H + +#include <asm-generic/mman.h> + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +#endif /* _ASM_MICROBLAZE_MMAN_H */ diff --git a/arch/microblaze/include/asm/mmu.h b/arch/microblaze/include/asm/mmu.h new file mode 100644 index 0000000..0e0431d --- /dev/null +++ b/arch/microblaze/include/asm/mmu.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_MMU_H +#define _ASM_MICROBLAZE_MMU_H + +#ifndef __ASSEMBLY__ +typedef struct { + struct vm_list_struct *vmlist; + unsigned long end_brk; +} mm_context_t; +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_MICROBLAZE_MMU_H */ diff --git a/arch/microblaze/include/asm/mmu_context.h b/arch/microblaze/include/asm/mmu_context.h new file mode 100644 index 0000000..150ca01 --- /dev/null +++ b/arch/microblaze/include/asm/mmu_context.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_MMU_CONTEXT_H +#define _ASM_MICROBLAZE_MMU_CONTEXT_H + +# define init_new_context(tsk, mm) ({ 0; }) + +# define enter_lazy_tlb(mm, tsk) do {} while (0) +# define change_mm_context(old, ctx, _pml4) do {} while (0) +# define destroy_context(mm) do {} while (0) +# define deactivate_mm(tsk, mm) do {} while (0) +# define switch_mm(prev, next, tsk) do {} while (0) +# define activate_mm(prev, next) do {} while (0) + +#endif /* _ASM_MICROBLAZE_MMU_CONTEXT_H */ diff --git a/arch/microblaze/include/asm/module.h b/arch/microblaze/include/asm/module.h new file mode 100644 index 0000000..914565a --- /dev/null +++ b/arch/microblaze/include/asm/module.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_MODULE_H +#define _ASM_MICROBLAZE_MODULE_H + +/* Microblaze Relocations */ +#define R_MICROBLAZE_NONE 0 +#define R_MICROBLAZE_32 1 +#define R_MICROBLAZE_32_PCREL 2 +#define R_MICROBLAZE_64_PCREL 3 +#define R_MICROBLAZE_32_PCREL_LO 4 +#define R_MICROBLAZE_64 5 +#define R_MICROBLAZE_32_LO 6 +#define R_MICROBLAZE_SRO32 7 +#define R_MICROBLAZE_SRW32 8 +#define R_MICROBLAZE_64_NONE 9 +#define R_MICROBLAZE_32_SYM_OP_SYM 10 +/* Keep this the last entry. */ +#define R_MICROBLAZE_NUM 11 + +struct mod_arch_specific { + int foo; +}; + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr + +typedef struct { volatile int counter; } module_t; + +#endif /* _ASM_MICROBLAZE_MODULE_H */ diff --git a/arch/microblaze/include/asm/msgbuf.h b/arch/microblaze/include/asm/msgbuf.h new file mode 100644 index 0000000..09dd970 --- /dev/null +++ b/arch/microblaze/include/asm/msgbuf.h @@ -0,0 +1,31 @@ +#ifndef _ASM_MICROBLAZE_MSGBUF_H +#define _ASM_MICROBLAZE_MSGBUF_H + +/* + * The msqid64_ds structure for microblaze architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _ASM_MICROBLAZE_MSGBUF_H */ diff --git a/arch/microblaze/include/asm/mutex.h b/arch/microblaze/include/asm/mutex.h new file mode 100644 index 0000000..ff6101a --- /dev/null +++ b/arch/microblaze/include/asm/mutex.h @@ -0,0 +1 @@ +#include <asm-generic/mutex-dec.h> diff --git a/arch/microblaze/include/asm/namei.h b/arch/microblaze/include/asm/namei.h new file mode 100644 index 0000000..61d60b8 --- /dev/null +++ b/arch/microblaze/include/asm/namei.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_NAMEI_H +#define _ASM_MICROBLAZE_NAMEI_H + +#ifdef __KERNEL__ + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ +#define __emul_prefix() NULL + +#endif /* __KERNEL__ */ + +#endif /* _ASM_MICROBLAZE_NAMEI_H */ diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h new file mode 100644 index 0000000..ba917cf --- /dev/null +++ b/arch/microblaze/include/asm/of_device.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> + * + * based on PowerPC of_device.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_OF_DEVICE_H +#define _ASM_MICROBLAZE_OF_DEVICE_H +#ifdef __KERNEL__ + +#include <linux/device.h> +#include <linux/of.h> + +/* + * The of_device is a kind of "base class" that is a superset of + * struct device for use by devices attached to an OF node and + * probed using OF properties. + */ +struct of_device { + struct device_node *node; /* to be obsoleted */ + u64 dma_mask; /* DMA mask */ + struct device dev; /* Generic device interface */ +}; + +extern ssize_t of_device_get_modalias(struct of_device *ofdev, + char *str, ssize_t len); + +extern struct of_device *of_device_alloc(struct device_node *np, + const char *bus_id, + struct device *parent); + +extern int of_device_uevent(struct device *dev, + struct kobj_uevent_env *env); + +extern void of_device_make_bus_id(struct of_device *dev); + +/* This is just here during the transition */ +#include <linux/of_device.h> + +#endif /* __KERNEL__ */ +#endif /* _ASM_MICROBLAZE_OF_DEVICE_H */ diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h new file mode 100644 index 0000000..187c0ee --- /dev/null +++ b/arch/microblaze/include/asm/of_platform.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. + * <benh@kernel.crashing.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MICROBLAZE_OF_PLATFORM_H +#define _ASM_MICROBLAZE_OF_PLATFORM_H + +/* This is just here during the transition */ +#include <linux/of_platform.h> + +/* + * The list of OF IDs below is used for matching bus types in the + * system whose devices are to be exposed as of_platform_devices. + * + * This is the default list valid for most platforms. This file provides + * functions who can take an explicit list if necessary though + * + * The search is always performed recursively looking for children of + * the provided device_node and recursively if such a children matches + * a bus type in the list + */ + +static const struct of_device_id of_default_bus_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + { .type = "plb5", }, + { .type = "plb4", }, + { .type = "opb", }, + { .type = "simple", }, + {}, +}; + +/* Platform drivers register/unregister */ +static inline int of_register_platform_driver(struct of_platform_driver *drv) +{ + return of_register_driver(drv, &of_platform_bus_type); +} +static inline void of_unregister_platform_driver(struct of_platform_driver *drv) +{ + of_unregister_driver(drv); +} + +/* Platform devices and busses creation */ +extern struct of_device *of_platform_device_create(struct device_node *np, + const char *bus_id, + struct device *parent); +/* pseudo "matches" value to not do deep probe */ +#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) + +extern int of_platform_bus_probe(struct device_node *root, + const struct of_device_id *matches, + struct device *parent); + +extern struct of_device *of_find_device_by_phandle(phandle ph); + +extern void of_instantiate_rtc(void); + +#endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */ diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h new file mode 100644 index 0000000..7238dcf --- /dev/null +++ b/arch/microblaze/include/asm/page.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2008 Michal Simek + * Copyright (C) 2008 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * Changes for MMU support: + * Copyright (C) 2007 Xilinx, Inc. All rights reserved. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_PAGE_H +#define _ASM_MICROBLAZE_PAGE_H + +#include <linux/pfn.h> +#include <asm/setup.h> + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT (12) +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) +#define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) + +/* align addr on a size boundary - adjust address up/down if needed */ +#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1))) + +/* align addr on a size boundary - adjust address up if needed */ +#define _ALIGN(addr, size) _ALIGN_UP(addr, size) + +/* + * PAGE_OFFSET -- the first address of the first page of memory. When not + * using MMU this corresponds to the first free page in physical memory (aligned + * on a page boundary). + */ +extern unsigned int __page_offset; +#define PAGE_OFFSET __page_offset + +#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) + + +#define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE) +#define copy_user_page(vto, vfrom, vaddr, topg) \ + memcpy((vto), (vfrom), PAGE_SIZE) + +/* + * These are used to make use of C type-checking.. + */ +typedef struct page *pgtable_t; +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct { unsigned long ste[64]; } pmd_t; +typedef struct { pmd_t pue[1]; } pud_t; +typedef struct { pud_t pge[1]; } pgd_t; + + +#define pte_val(x) ((x).pte) +#define pgprot_val(x) ((x).pgprot) +#define pmd_val(x) ((x).ste[0]) +#define pud_val(x) ((x).pue[0]) +#define pgd_val(x) ((x).pge[0]) + +#define __pte(x) ((pte_t) { (x) }) +#define __pmd(x) ((pmd_t) { (x) }) +#define __pgd(x) ((pgd_t) { (x) }) +#define __pgprot(x) ((pgprot_t) { (x) }) + +/** + * Conversions for virtual address, physical address, pfn, and struct + * page are defined in the following files. + * + * virt -+ + * | asm-microblaze/page.h + * phys -+ + * | linux/pfn.h + * pfn -+ + * | asm-generic/memory_model.h + * page -+ + * + */ + +extern unsigned long max_low_pfn; +extern unsigned long min_low_pfn; +extern unsigned long max_pfn; + +#define __pa(vaddr) ((unsigned long) (vaddr)) +#define __va(paddr) ((void *) (paddr)) + +#define phys_to_pfn(phys) (PFN_DOWN(phys)) +#define pfn_to_phys(pfn) (PFN_PHYS(pfn)) + +#define virt_to_pfn(vaddr) (phys_to_pfn((__pa(vaddr)))) +#define pfn_to_virt(pfn) __va(pfn_to_phys((pfn))) + +#define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr))) +#define page_to_virt(page) (pfn_to_virt(page_to_pfn(page))) + +#define page_to_phys(page) (pfn_to_phys(page_to_pfn(page))) +#define page_to_bus(page) (page_to_phys(page)) +#define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr))) + +extern unsigned int memory_start; +extern unsigned int memory_end; +extern unsigned int memory_size; + +#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_mapnr) + +#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) + +#else +#define tophys(rd, rs) (addik rd, rs, 0) +#define tovirt(rd, rs) (addik rd, rs, 0) +#endif /* __ASSEMBLY__ */ + +#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr))) + +/* Convert between virtual and physical address for MMU. */ +/* Handle MicroBlaze processor with virtual memory. */ +#define __virt_to_phys(addr) addr +#define __phys_to_virt(addr) addr + +#define TOPHYS(addr) __virt_to_phys(addr) + +#endif /* __KERNEL__ */ + +#include <asm-generic/memory_model.h> +#include <asm-generic/page.h> + +#endif /* _ASM_MICROBLAZE_PAGE_H */ diff --git a/arch/microblaze/include/asm/param.h b/arch/microblaze/include/asm/param.h new file mode 100644 index 0000000..8c538a4 --- /dev/null +++ b/arch/microblaze/include/asm/param.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_PARAM_H +#define _ASM_MICROBLAZE_PARAM_H + +#ifdef __KERNEL__ +#define HZ CONFIG_HZ /* internal kernel timer frequency */ +#define USER_HZ 100 /* for user interfaces in "ticks" */ +#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ +#endif /* __KERNEL__ */ + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _ASM_MICROBLAZE_PARAM_H */ diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h new file mode 100644 index 0000000..7ad28f6 --- /dev/null +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -0,0 +1 @@ +#include <linux/pci.h> diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h new file mode 100644 index 0000000..ca03794 --- /dev/null +++ b/arch/microblaze/include/asm/pci.h @@ -0,0 +1 @@ +#include <linux/io.h> diff --git a/arch/microblaze/include/asm/percpu.h b/arch/microblaze/include/asm/percpu.h new file mode 100644 index 0000000..06a959d --- /dev/null +++ b/arch/microblaze/include/asm/percpu.h @@ -0,0 +1 @@ +#include <asm-generic/percpu.h> diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h new file mode 100644 index 0000000..2a4b354 --- /dev/null +++ b/arch/microblaze/include/asm/pgalloc.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_PGALLOC_H +#define _ASM_MICROBLAZE_PGALLOC_H + +#define check_pgt_cache() do {} while (0) + +#endif /* _ASM_MICROBLAZE_PGALLOC_H */ diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h new file mode 100644 index 0000000..4df31e4 --- /dev/null +++ b/arch/microblaze/include/asm/pgtable.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_PGTABLE_H +#define _ASM_MICROBLAZE_PGTABLE_H + +#include <asm/setup.h> + +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define pgd_present(pgd) (1) /* pages are always present on non MMU */ +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_clear(pgdp) +#define kern_addr_valid(addr) (1) +#define pmd_offset(a, b) ((void *) 0) + +#define PAGE_NONE __pgprot(0) /* these mean nothing to non MMU */ +#define PAGE_SHARED __pgprot(0) /* these mean nothing to non MMU */ +#define PAGE_COPY __pgprot(0) /* these mean nothing to non MMU */ +#define PAGE_READONLY __pgprot(0) /* these mean nothing to non MMU */ +#define PAGE_KERNEL __pgprot(0) /* these mean nothing to non MMU */ + +#define __swp_type(x) (0) +#define __swp_offset(x) (0) +#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +#ifndef __ASSEMBLY__ +static inline int pte_file(pte_t pte) { return 0; } +#endif /* __ASSEMBLY__ */ + +#define ZERO_PAGE(vaddr) ({ BUG(); NULL; }) + +#define swapper_pg_dir ((pgd_t *) NULL) + +#define pgtable_cache_init() do {} while (0) + +#define arch_enter_lazy_cpu_mode() do {} while (0) + +#ifndef __ASSEMBLY__ +#include <asm-generic/pgtable.h> + +void setup_memory(void); +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_MICROBLAZE_PGTABLE_H */ diff --git a/arch/microblaze/include/asm/poll.h b/arch/microblaze/include/asm/poll.h new file mode 100644 index 0000000..c98509d --- /dev/null +++ b/arch/microblaze/include/asm/poll.h @@ -0,0 +1 @@ +#include <asm-generic/poll.h> diff --git a/arch/microblaze/include/asm/posix_types.h b/arch/microblaze/include/asm/posix_types.h new file mode 100644 index 0000000..b4df41c --- /dev/null +++ b/arch/microblaze/include/asm/posix_types.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_POSIX_TYPES_H +#define _ASM_MICROBLAZE_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned int __kernel_mode_t; +typedef unsigned int __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned int __kernel_ipc_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char *__kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned int __kernel_old_uid_t; +typedef unsigned int __kernel_old_gid_t; +typedef unsigned int __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) + +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) + +#undef __FD_ISSET +#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d))) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset(fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif /* _ASM_MICROBLAZE_POSIX_TYPES_H */ diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h new file mode 100644 index 0000000..d8e1543 --- /dev/null +++ b/arch/microblaze/include/asm/processor.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2008 Michal Simek + * Copyright (C) 2008 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_PROCESSOR_H +#define _ASM_MICROBLAZE_PROCESSOR_H + +#include <asm/ptrace.h> +#include <asm/setup.h> +#include <asm/registers.h> +#include <asm/segment.h> + +# ifndef __ASSEMBLY__ +/* from kernel/cpu/mb.c */ +extern const struct seq_operations cpuinfo_op; + +# define cpu_relax() barrier() +# define cpu_sleep() do {} while (0) +# define prepare_to_copy(tsk) do {} while (0) + +# endif /* __ASSEMBLY__ */ + +/* + * User space process size: memory size + * + * TASK_SIZE on MMU cpu is usually 1GB. However, on no-MMU arch, both + * user processes and the kernel is on the same memory region. They + * both share the memory space and that is limited by the amount of + * physical memory. thus, we set TASK_SIZE == amount of total memory. + */ +# define TASK_SIZE (0x81000000 - 0x80000000) + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +# define current_text_addr() ({ __label__ _l; _l: &&_l; }) + +/* + * This decides where the kernel will search for a free chunk of vm + * space during mmap's. We won't be using it + */ +# define TASK_UNMAPPED_BASE 0 + +/* definition in include/linux/sched.h */ +struct task_struct; + +/* thread_struct is gone. use thread_info instead. */ +struct thread_struct { }; +# define INIT_THREAD { } + +/* Do necessary setup to start up a newly executed thread. */ +static inline void start_thread(struct pt_regs *regs, + unsigned long pc, + unsigned long usp) +{ + regs->pc = pc; + regs->r1 = usp; + regs->kernel_mode = 0; +} + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +/* Free all resources held by a thread. */ +static inline void exit_thread(void) +{ +} + +extern unsigned long thread_saved_pc(struct task_struct *t); + +extern unsigned long get_wchan(struct task_struct *p); + +/* + * create a kernel thread without removing it from tasklists + */ +extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); + +# define task_pt_regs(tsk) \ + (((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1) + +# define KSTK_EIP(tsk) (0) +# define KSTK_ESP(tsk) (0) + +#endif /* _ASM_MICROBLAZE_PROCESSOR_H */ diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h new file mode 100644 index 0000000..20f7b3a9 --- /dev/null +++ b/arch/microblaze/include/asm/prom.h @@ -0,0 +1,313 @@ +/* + * Definitions for talking to the Open Firmware PROM on + * Power Macintosh computers. + * + * Copyright (C) 1996-2005 Paul Mackerras. + * + * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_MICROBLAZE_PROM_H +#define _ASM_MICROBLAZE_PROM_H +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <linux/proc_fs.h> +#include <linux/platform_device.h> +#include <asm/irq.h> +#include <asm/atomic.h> + +#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1 +#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 + +#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l)) +#define of_prop_cmp(s1, s2) strcmp((s1), (s2)) +#define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) + +/* Definitions used by the flattened device tree */ +#define OF_DT_HEADER 0xd00dfeed /* marker */ +#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ +#define OF_DT_END_NODE 0x2 /* End node */ +#define OF_DT_PROP 0x3 /* Property: name off, size, content */ +#define OF_DT_NOP 0x4 /* nop */ +#define OF_DT_END 0x9 + +#define OF_DT_VERSION 0x10 + +/* + * This is what gets passed to the kernel by prom_init or kexec + * + * The dt struct contains the device tree structure, full pathes and + * property contents. The dt strings contain a separate block with just + * the strings for the property names, and is fully page aligned and + * self contained in a page, so that it can be kept around by the kernel, + * each property name appears only once in this page (cheap compression) + * + * the mem_rsvmap contains a map of reserved ranges of physical memory, + * passing it here instead of in the device-tree itself greatly simplifies + * the job of everybody. It's just a list of u64 pairs (base/size) that + * ends when size is 0 + */ +struct boot_param_header { + u32 magic; /* magic word OF_DT_HEADER */ + u32 totalsize; /* total size of DT block */ + u32 off_dt_struct; /* offset to structure */ + u32 off_dt_strings; /* offset to strings */ + u32 off_mem_rsvmap; /* offset to memory reserve map */ + u32 version; /* format version */ + u32 last_comp_version; /* last compatible version */ + /* version 2 fields below */ + u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ + /* version 3 fields below */ + u32 dt_strings_size; /* size of the DT strings block */ + /* version 17 fields below */ + u32 dt_struct_size; /* size of the DT structure block */ +}; + +typedef u32 phandle; +typedef u32 ihandle; + +struct property { + char *name; + int length; + void *value; + struct property *next; +}; + +struct device_node { + const char *name; + const char *type; + phandle node; + phandle linux_phandle; + char *full_name; + + struct property *properties; + struct property *deadprops; /* removed properties */ + struct device_node *parent; + struct device_node *child; + struct device_node *sibling; + struct device_node *next; /* next device of same type */ + struct device_node *allnext; /* next in list of all nodes */ + struct proc_dir_entry *pde; /* this node's proc directory */ + struct kref kref; + unsigned long _flags; + void *data; +}; + +extern struct device_node *of_chosen; + +static inline int of_node_check_flag(struct device_node *n, unsigned long flag) +{ + return test_bit(flag, &n->_flags); +} + +static inline void of_node_set_flag(struct device_node *n, unsigned long flag) +{ + set_bit(flag, &n->_flags); +} + +#define HAVE_ARCH_DEVTREE_FIXUPS + +static inline void set_node_proc_entry(struct device_node *dn, + struct proc_dir_entry *de) +{ + dn->pde = de; +} + +extern struct device_node *allnodes; /* temporary while merging */ +extern rwlock_t devtree_lock; /* temporary while merging */ + +extern struct device_node *of_find_all_nodes(struct device_node *prev); +extern struct device_node *of_node_get(struct device_node *node); +extern void of_node_put(struct device_node *node); + +/* For scanning the flat device-tree at boot time */ +extern int __init of_scan_flat_dt(int (*it)(unsigned long node, + const char *uname, int depth, + void *data), + void *data); +extern void *__init of_get_flat_dt_prop(unsigned long node, const char *name, + unsigned long *size); +extern int __init + of_flat_dt_is_compatible(unsigned long node, const char *name); +extern unsigned long __init of_get_flat_dt_root(void); + +/* For updating the device tree at runtime */ +extern void of_attach_node(struct device_node *); +extern void of_detach_node(struct device_node *); + +/* Other Prototypes */ +extern void finish_device_tree(void); +extern void unflatten_device_tree(void); +extern int early_uartlite_console(void); +extern void early_init_devtree(void *); +extern int machine_is_compatible(const char *compat); +extern void print_properties(struct device_node *node); +extern int prom_n_intr_cells(struct device_node *np); +extern void prom_get_irq_senses(unsigned char *senses, int off, int max); +extern int prom_add_property(struct device_node *np, struct property *prop); +extern int prom_remove_property(struct device_node *np, struct property *prop); +extern int prom_update_property(struct device_node *np, + struct property *newprop, + struct property *oldprop); + +extern struct resource *request_OF_resource(struct device_node *node, + int index, const char *name_postfix); +extern int release_OF_resource(struct device_node *node, int index); + +/* + * OF address retreival & translation + */ + +/* Helper to read a big number; size is in cells (not bytes) */ +static inline u64 of_read_number(const u32 *cell, int size) +{ + u64 r = 0; + while (size--) + r = (r << 32) | *(cell++); + return r; +} + +/* Like of_read_number, but we want an unsigned long result */ +#define of_read_ulong(cell, size) of_read_number(cell, size) + +/* Translate an OF address block into a CPU physical address + */ +extern u64 of_translate_address(struct device_node *np, const u32 *addr); + +/* Extract an address from a device, returns the region size and + * the address space flags too. The PCI version uses a BAR number + * instead of an absolute index + */ +extern const u32 *of_get_address(struct device_node *dev, int index, + u64 *size, unsigned int *flags); +extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, + u64 *size, unsigned int *flags); + +/* Get an address as a resource. Note that if your address is + * a PIO address, the conversion will fail if the physical address + * can't be internally converted to an IO token with + * pci_address_to_pio(), that is because it's either called to early + * or it can't be matched to any host bridge IO space + */ +extern int of_address_to_resource(struct device_node *dev, int index, + struct resource *r); +extern int of_pci_address_to_resource(struct device_node *dev, int bar, + struct resource *r); + +/* Parse the ibm,dma-window property of an OF node into the busno, phys and + * size parameters. + */ +void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, + unsigned long *busno, unsigned long *phys, unsigned long *size); + +extern void kdump_move_device_tree(void); + +/* CPU OF node matching */ +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); + +/* Get the MAC address */ +extern const void *of_get_mac_address(struct device_node *np); + +/* + * OF interrupt mapping + */ + +/* This structure is returned when an interrupt is mapped. The controller + * field needs to be put() after use + */ + +#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */ + +struct of_irq { + struct device_node *controller; /* Interrupt controller node */ + u32 size; /* Specifier size */ + u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ +}; + +/** + * of_irq_map_init - Initialize the irq remapper + * @flags: flags defining workarounds to enable + * + * Some machines have bugs in the device-tree which require certain workarounds + * to be applied. Call this before any interrupt mapping attempts to enable + * those workarounds. + */ +#define OF_IMAP_OLDWORLD_MAC 0x00000001 +#define OF_IMAP_NO_PHANDLE 0x00000002 + +extern void of_irq_map_init(unsigned int flags); + +/** + * of_irq_map_raw - Low level interrupt tree parsing + * @parent: the device interrupt parent + * @intspec: interrupt specifier ("interrupts" property of the device) + * @ointsize: size of the passed in interrupt specifier + * @addr: address specifier (start of "reg" property of the device) + * @out_irq: structure of_irq filled by this function + * + * Returns 0 on success and a negative number on error + * + * This function is a low-level interrupt tree walking function. It + * can be used to do a partial walk with synthetized reg and interrupts + * properties, for example when resolving PCI interrupts when no device + * node exist for the parent. + * + */ + +extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, + u32 ointsize, const u32 *addr, + struct of_irq *out_irq); + +/** + * of_irq_map_one - Resolve an interrupt for a device + * @device: the device whose interrupt is to be resolved + * @index: index of the interrupt to resolve + * @out_irq: structure of_irq filled by this function + * + * This function resolves an interrupt, walking the tree, for a given + * device-tree node. It's the high level pendant to of_irq_map_raw(). + * It also implements the workarounds for OldWolrd Macs. + */ +extern int of_irq_map_one(struct device_node *device, int index, + struct of_irq *out_irq); + +/** + * of_irq_map_pci - Resolve the interrupt for a PCI device + * @pdev: the device whose interrupt is to be resolved + * @out_irq: structure of_irq filled by this function + * + * This function resolves the PCI interrupt for a given PCI device. If a + * device-node exists for a given pci_dev, it will use normal OF tree + * walking. If not, it will implement standard swizzling and walk up the + * PCI tree until an device-node is found, at which point it will finish + * resolving using the OF tree walking. + */ +struct pci_dev; +extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); + +extern int of_irq_to_resource(struct device_node *dev, int index, + struct resource *r); + +/** + * of_iomap - Maps the memory mapped IO for a given device_node + * @device: the device whose io range will be mapped + * @index: index of the io range + * + * Returns a pointer to the mapped memory + */ +extern void __iomem *of_iomap(struct device_node *device, int index); + +/* + * NB: This is here while we transition from using asm/prom.h + * to linux/of.h + */ +#include <linux/of.h> + +#endif /* __KERNEL__ */ +#endif /* _ASM_MICROBLAZE_PROM_H */ diff --git a/arch/microblaze/include/asm/ptrace.h b/arch/microblaze/include/asm/ptrace.h new file mode 100644 index 0000000..f1f0348 --- /dev/null +++ b/arch/microblaze/include/asm/ptrace.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_PTRACE_H +#define _ASM_MICROBLAZE_PTRACE_H + +#ifndef __ASSEMBLY__ +#include <linux/types.h> + +typedef unsigned long microblaze_reg_t; + +struct pt_regs { + microblaze_reg_t r0; + microblaze_reg_t r1; + microblaze_reg_t r2; + microblaze_reg_t r3; + microblaze_reg_t r4; + microblaze_reg_t r5; + microblaze_reg_t r6; + microblaze_reg_t r7; + microblaze_reg_t r8; + microblaze_reg_t r9; + microblaze_reg_t r10; + microblaze_reg_t r11; + microblaze_reg_t r12; + microblaze_reg_t r13; + microblaze_reg_t r14; + microblaze_reg_t r15; + microblaze_reg_t r16; + microblaze_reg_t r17; + microblaze_reg_t r18; + microblaze_reg_t r19; + microblaze_reg_t r20; + microblaze_reg_t r21; + microblaze_reg_t r22; + microblaze_reg_t r23; + microblaze_reg_t r24; + microblaze_reg_t r25; + microblaze_reg_t r26; + microblaze_reg_t r27; + microblaze_reg_t r28; + microblaze_reg_t r29; + microblaze_reg_t r30; + microblaze_reg_t r31; + microblaze_reg_t pc; + microblaze_reg_t msr; + microblaze_reg_t ear; + microblaze_reg_t esr; + microblaze_reg_t fsr; + int kernel_mode; +}; + +#define kernel_mode(regs) ((regs)->kernel_mode) +#define user_mode(regs) (!kernel_mode(regs)) + +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) + +void show_regs(struct pt_regs *); + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_MICROBLAZE_PTRACE_H */ diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h new file mode 100644 index 0000000..66f1b30 --- /dev/null +++ b/arch/microblaze/include/asm/pvr.h @@ -0,0 +1,209 @@ +/* + * Support for the MicroBlaze PVR (Processor Version Register) + * + * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * Copyright (C) 2007 - 2009 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#ifndef _ASM_MICROBLAZE_PVR_H +#define _ASM_MICROBLAZE_PVR_H + +#define PVR_MSR_BIT 0x400 + +struct pvr_s { + unsigned pvr[16]; +}; + +/* The following taken from Xilinx's standalone BSP pvr.h */ + +/* Basic PVR mask */ +#define PVR0_PVR_FULL_MASK 0x80000000 +#define PVR0_USE_BARREL_MASK 0x40000000 +#define PVR0_USE_DIV_MASK 0x20000000 +#define PVR0_USE_HW_MUL_MASK 0x10000000 +#define PVR0_USE_FPU_MASK 0x08000000 +#define PVR0_USE_EXC_MASK 0x04000000 +#define PVR0_USE_ICACHE_MASK 0x02000000 +#define PVR0_USE_DCACHE_MASK 0x01000000 +#define PVR0_USE_MMU 0x00800000 /* new */ +#define PVR0_VERSION_MASK 0x0000FF00 +#define PVR0_USER1_MASK 0x000000FF + +/* User 2 PVR mask */ +#define PVR1_USER2_MASK 0xFFFFFFFF + +/* Configuration PVR masks */ +#define PVR2_D_OPB_MASK 0x80000000 +#define PVR2_D_LMB_MASK 0x40000000 +#define PVR2_I_OPB_MASK 0x20000000 +#define PVR2_I_LMB_MASK 0x10000000 +#define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000 +#define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000 +#define PVR2_D_PLB_MASK 0x02000000 /* new */ +#define PVR2_I_PLB_MASK 0x01000000 /* new */ +#define PVR2_INTERCONNECT 0x00800000 /* new */ +#define PVR2_USE_EXTEND_FSL 0x00080000 /* new */ +#define PVR2_USE_FSL_EXC 0x00040000 /* new */ +#define PVR2_USE_MSR_INSTR 0x00020000 +#define PVR2_USE_PCMP_INSTR 0x00010000 +#define PVR2_AREA_OPTIMISED 0x00008000 +#define PVR2_USE_BARREL_MASK 0x00004000 +#define PVR2_USE_DIV_MASK 0x00002000 +#define PVR2_USE_HW_MUL_MASK 0x00001000 +#define PVR2_USE_FPU_MASK 0x00000800 +#define PVR2_USE_MUL64_MASK 0x00000400 +#define PVR2_USE_FPU2_MASK 0x00000200 /* new */ +#define PVR2_USE_IPLBEXC 0x00000100 +#define PVR2_USE_DPLBEXC 0x00000080 +#define PVR2_OPCODE_0x0_ILL_MASK 0x00000040 +#define PVR2_UNALIGNED_EXC_MASK 0x00000020 +#define PVR2_ILL_OPCODE_EXC_MASK 0x00000010 +#define PVR2_IOPB_BUS_EXC_MASK 0x00000008 +#define PVR2_DOPB_BUS_EXC_MASK 0x00000004 +#define PVR2_DIV_ZERO_EXC_MASK 0x00000002 +#define PVR2_FPU_EXC_MASK 0x00000001 + +/* Debug and exception PVR masks */ +#define PVR3_DEBUG_ENABLED_MASK 0x80000000 +#define PVR3_NUMBER_OF_PC_BRK_MASK 0x1E000000 +#define PVR3_NUMBER_OF_RD_ADDR_BRK_MASK 0x00380000 +#define PVR3_NUMBER_OF_WR_ADDR_BRK_MASK 0x0000E000 +#define PVR3_FSL_LINKS_MASK 0x00000380 + +/* ICache config PVR masks */ +#define PVR4_USE_ICACHE_MASK 0x80000000 +#define PVR4_ICACHE_ADDR_TAG_BITS_MASK 0x7C000000 +#define PVR4_ICACHE_USE_FSL_MASK 0x02000000 +#define PVR4_ICACHE_ALLOW_WR_MASK 0x01000000 +#define PVR4_ICACHE_LINE_LEN_MASK 0x00E00000 +#define PVR4_ICACHE_BYTE_SIZE_MASK 0x001F0000 + +/* DCache config PVR masks */ +#define PVR5_USE_DCACHE_MASK 0x80000000 +#define PVR5_DCACHE_ADDR_TAG_BITS_MASK 0x7C000000 +#define PVR5_DCACHE_USE_FSL_MASK 0x02000000 +#define PVR5_DCACHE_ALLOW_WR_MASK 0x01000000 +#define PVR5_DCACHE_LINE_LEN_MASK 0x00E00000 +#define PVR5_DCACHE_BYTE_SIZE_MASK 0x001F0000 + +/* ICache base address PVR mask */ +#define PVR6_ICACHE_BASEADDR_MASK 0xFFFFFFFF + +/* ICache high address PVR mask */ +#define PVR7_ICACHE_HIGHADDR_MASK 0xFFFFFFFF + +/* DCache base address PVR mask */ +#define PVR8_DCACHE_BASEADDR_MASK 0xFFFFFFFF + +/* DCache high address PVR mask */ +#define PVR9_DCACHE_HIGHADDR_MASK 0xFFFFFFFF + +/* Target family PVR mask */ +#define PVR10_TARGET_FAMILY_MASK 0xFF000000 + +/* MMU descrtiption */ +#define PVR11_USE_MMU 0xC0000000 +#define PVR11_MMU_ITLB_SIZE 0x38000000 +#define PVR11_MMU_DTLB_SIZE 0x07000000 +#define PVR11_MMU_TLB_ACCESS 0x00C00000 +#define PVR11_MMU_ZONES 0x003C0000 +/* MSR Reset value PVR mask */ +#define PVR11_MSR_RESET_VALUE_MASK 0x000007FF + + +/* PVR access macros */ +#define PVR_IS_FULL(pvr) (pvr.pvr[0] & PVR0_PVR_FULL_MASK) +#define PVR_USE_BARREL(pvr) (pvr.pvr[0] & PVR0_USE_BARREL_MASK) +#define PVR_USE_DIV(pvr) (pvr.pvr[0] & PVR0_USE_DIV_MASK) +#define PVR_USE_HW_MUL(pvr) (pvr.pvr[0] & PVR0_USE_HW_MUL_MASK) +#define PVR_USE_FPU(pvr) (pvr.pvr[0] & PVR0_USE_FPU_MASK) +#define PVR_USE_FPU2(pvr) (pvr.pvr[2] & PVR2_USE_FPU2_MASK) +#define PVR_USE_ICACHE(pvr) (pvr.pvr[0] & PVR0_USE_ICACHE_MASK) +#define PVR_USE_DCACHE(pvr) (pvr.pvr[0] & PVR0_USE_DCACHE_MASK) +#define PVR_VERSION(pvr) ((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8) +#define PVR_USER1(pvr) (pvr.pvr[0] & PVR0_USER1_MASK) +#define PVR_USER2(pvr) (pvr.pvr[1] & PVR1_USER2_MASK) + +#define PVR_D_OPB(pvr) (pvr.pvr[2] & PVR2_D_OPB_MASK) +#define PVR_D_LMB(pvr) (pvr.pvr[2] & PVR2_D_LMB_MASK) +#define PVR_I_OPB(pvr) (pvr.pvr[2] & PVR2_I_OPB_MASK) +#define PVR_I_LMB(pvr) (pvr.pvr[2] & PVR2_I_LMB_MASK) +#define PVR_INTERRUPT_IS_EDGE(pvr) \ + (pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK) +#define PVR_EDGE_IS_POSITIVE(pvr) \ + (pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK) +#define PVR_USE_MSR_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_MSR_INSTR) +#define PVR_USE_PCMP_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_PCMP_INSTR) +#define PVR_AREA_OPTIMISED(pvr) (pvr.pvr[2] & PVR2_AREA_OPTIMISED) +#define PVR_USE_MUL64(pvr) (pvr.pvr[2] & PVR2_USE_MUL64_MASK) +#define PVR_OPCODE_0x0_ILLEGAL(pvr) \ + (pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK) +#define PVR_UNALIGNED_EXCEPTION(pvr) \ + (pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK) +#define PVR_ILL_OPCODE_EXCEPTION(pvr) \ + (pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK) +#define PVR_IOPB_BUS_EXCEPTION(pvr) \ + (pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK) +#define PVR_DOPB_BUS_EXCEPTION(pvr) \ + (pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK) +#define PVR_DIV_ZERO_EXCEPTION(pvr) \ + (pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK) +#define PVR_FPU_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_FPU_EXC_MASK) +#define PVR_FSL_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_USE_EXTEND_FSL) + +#define PVR_DEBUG_ENABLED(pvr) (pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK) +#define PVR_NUMBER_OF_PC_BRK(pvr) \ + ((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25) +#define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \ + ((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19) +#define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \ + ((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13) +#define PVR_FSL_LINKS(pvr) ((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7) + +#define PVR_ICACHE_ADDR_TAG_BITS(pvr) \ + ((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26) +#define PVR_ICACHE_USE_FSL(pvr) (pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK) +#define PVR_ICACHE_ALLOW_WR(pvr) (pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK) +#define PVR_ICACHE_LINE_LEN(pvr) \ + (1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21)) +#define PVR_ICACHE_BYTE_SIZE(pvr) \ + (1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16)) + +#define PVR_DCACHE_ADDR_TAG_BITS(pvr) \ + ((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26) +#define PVR_DCACHE_USE_FSL(pvr) (pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK) +#define PVR_DCACHE_ALLOW_WR(pvr) (pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK) +#define PVR_DCACHE_LINE_LEN(pvr) \ + (1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21)) +#define PVR_DCACHE_BYTE_SIZE(pvr) \ + (1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16)) + + +#define PVR_ICACHE_BASEADDR(pvr) (pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK) +#define PVR_ICACHE_HIGHADDR(pvr) (pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK) + +#define PVR_DCACHE_BASEADDR(pvr) (pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK) +#define PVR_DCACHE_HIGHADDR(pvr) (pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK) + +#define PVR_TARGET_FAMILY(pvr) ((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24) + +#define PVR_MSR_RESET_VALUE(pvr) \ + (pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK) + +/* mmu */ +#define PVR_USE_MMU(pvr) ((pvr.pvr[11] & PVR11_USE_MMU) >> 30) +#define PVR_MMU_ITLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_ITLB_SIZE) +#define PVR_MMU_DTLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_DTLB_SIZE) +#define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS) +#define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES) + + +int cpu_has_pvr(void); +void get_pvr(struct pvr_s *pvr); + +#endif /* _ASM_MICROBLAZE_PVR_H */ diff --git a/arch/microblaze/include/asm/registers.h b/arch/microblaze/include/asm/registers.h new file mode 100644 index 0000000..834142d --- /dev/null +++ b/arch/microblaze/include/asm/registers.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 Michal Simek + * Copyright (C) 2008 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_REGISTERS_H +#define _ASM_MICROBLAZE_REGISTERS_H + +#define MSR_BE (1<<0) /* 0x001 */ +#define MSR_IE (1<<1) /* 0x002 */ +#define MSR_C (1<<2) /* 0x004 */ +#define MSR_BIP (1<<3) /* 0x008 */ +#define MSR_FSL (1<<4) /* 0x010 */ +#define MSR_ICE (1<<5) /* 0x020 */ +#define MSR_DZ (1<<6) /* 0x040 */ +#define MSR_DCE (1<<7) /* 0x080 */ +#define MSR_EE (1<<8) /* 0x100 */ +#define MSR_EIP (1<<9) /* 0x200 */ +#define MSR_CC (1<<31) + +/* Floating Point Status Register (FSR) Bits */ +#define FSR_IO (1<<4) /* Invalid operation */ +#define FSR_DZ (1<<3) /* Divide-by-zero */ +#define FSR_OF (1<<2) /* Overflow */ +#define FSR_UF (1<<1) /* Underflow */ +#define FSR_DO (1<<0) /* Denormalized operand error */ + +#endif /* _ASM_MICROBLAZE_REGISTERS_H */ diff --git a/arch/microblaze/include/asm/resource.h b/arch/microblaze/include/asm/resource.h new file mode 100644 index 0000000..04bc4db --- /dev/null +++ b/arch/microblaze/include/asm/resource.h @@ -0,0 +1 @@ +#include <asm-generic/resource.h> diff --git a/arch/microblaze/include/asm/scatterlist.h b/arch/microblaze/include/asm/scatterlist.h new file mode 100644 index 0000000..08ff1d0 --- /dev/null +++ b/arch/microblaze/include/asm/scatterlist.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2008 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SCATTERLIST_H +#define _ASM_MICROBLAZE_SCATTERLIST_H + +struct scatterlist { +#ifdef CONFIG_DEBUG_SG + unsigned long sg_magic; +#endif + unsigned long page_link; + dma_addr_t dma_address; + unsigned int offset; + unsigned int length; +}; + +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->length) + +#define ISA_DMA_THRESHOLD (~0UL) + +#endif /* _ASM_MICROBLAZE_SCATTERLIST_H */ diff --git a/arch/microblaze/include/asm/sections.h b/arch/microblaze/include/asm/sections.h new file mode 100644 index 0000000..8434a43 --- /dev/null +++ b/arch/microblaze/include/asm/sections.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SECTIONS_H +#define _ASM_MICROBLAZE_SECTIONS_H + +#include <asm-generic/sections.h> + +# ifndef __ASSEMBLY__ +extern char _ssbss[], _esbss[]; +extern unsigned long __ivt_start[], __ivt_end[]; + +# ifdef CONFIG_MTD_UCLINUX +extern char *_ebss; +# endif + +extern u32 _fdt_start[], _fdt_end[]; + +# endif /* !__ASSEMBLY__ */ +#endif /* _ASM_MICROBLAZE_SECTIONS_H */ diff --git a/arch/microblaze/include/asm/segment.h b/arch/microblaze/include/asm/segment.h new file mode 100644 index 0000000..7f5dcc5 --- /dev/null +++ b/arch/microblaze/include/asm/segment.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 Michal Simek + * Copyright (C) 2008 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SEGMENT_H +#define _ASM_MICROBLAZE_SEGMENT_H + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned long seg; +} mm_segment_t; + +/* + * On Microblaze the fs value is actually the top of the corresponding + * address space. + * + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + * + * For historical reasons, these macros are grossly misnamed. + * + * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal. + */ +# define KERNEL_DS ((mm_segment_t){0}) +# define USER_DS KERNEL_DS + +# define get_ds() (KERNEL_DS) +# define get_fs() (current_thread_info()->addr_limit) +# define set_fs(x) \ + do { current_thread_info()->addr_limit = (x); } while (0) + +# define segment_eq(a, b) ((a).seg == (b).seg) + +# endif /* __ASSEMBLY__ */ +#endif /* _ASM_MICROBLAZE_SEGMENT_H */ diff --git a/arch/microblaze/include/asm/selfmod.h b/arch/microblaze/include/asm/selfmod.h new file mode 100644 index 0000000..c42aff2 --- /dev/null +++ b/arch/microblaze/include/asm/selfmod.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SELFMOD_H +#define _ASM_MICROBLAZE_SELFMOD_H + +/* + * BARRIER_BASE_ADDR is constant address for selfmod function. + * do not change this value - selfmod function is in + * arch/microblaze/kernel/selfmod.c: selfmod_function() + * + * last 16 bits is used for storing register offset + */ + +#define BARRIER_BASE_ADDR 0x1234ff00 + +void selfmod_function(const int *arr_fce, const unsigned int base); + +#endif /* _ASM_MICROBLAZE_SELFMOD_H */ diff --git a/arch/microblaze/include/asm/sembuf.h b/arch/microblaze/include/asm/sembuf.h new file mode 100644 index 0000000..b804ed7 --- /dev/null +++ b/arch/microblaze/include/asm/sembuf.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SEMBUF_H +#define _ASM_MICROBLAZE_SEMBUF_H + +/* + * The semid64_ds structure for microblaze architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + + +#endif /* _ASM_MICROBLAZE_SEMBUF_H */ diff --git a/arch/microblaze/include/asm/serial.h b/arch/microblaze/include/asm/serial.h new file mode 100644 index 0000000..39bfc8c --- /dev/null +++ b/arch/microblaze/include/asm/serial.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SERIAL_H +#define _ASM_MICROBLAZE_SERIAL_H + +# define BASE_BAUD (1843200 / 16) + +#endif /* _ASM_MICROBLAZE_SERIAL_H */ diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h new file mode 100644 index 0000000..9b98e8e --- /dev/null +++ b/arch/microblaze/include/asm/setup.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SETUP_H +#define _ASM_MICROBLAZE_SETUP_H + +#define COMMAND_LINE_SIZE 256 + +# ifndef __ASSEMBLY__ + +# ifdef __KERNEL__ +extern unsigned int boot_cpuid; /* move to smp.h */ + +extern char cmd_line[COMMAND_LINE_SIZE]; +# endif/* __KERNEL__ */ + +void early_printk(const char *fmt, ...); + +int setup_early_printk(char *opt); +void disable_early_printk(void); + +void heartbeat(void); +void setup_heartbeat(void); + +unsigned long long sched_clock(void); + +void time_init(void); +void init_IRQ(void); +void machine_early_init(const char *cmdline, unsigned int ram, + unsigned int fdt); + +void machine_restart(char *cmd); +void machine_shutdown(void); +void machine_halt(void); +void machine_power_off(void); + +# endif /* __ASSEMBLY__ */ +#endif /* _ASM_MICROBLAZE_SETUP_H */ diff --git a/arch/microblaze/include/asm/shmbuf.h b/arch/microblaze/include/asm/shmbuf.h new file mode 100644 index 0000000..f829c58 --- /dev/null +++ b/arch/microblaze/include/asm/shmbuf.h @@ -0,0 +1,42 @@ +#ifndef _ASM_MICROBLAZE_SHMBUF_H +#define _ASM_MICROBLAZE_SHMBUF_H + +/* + * The shmid64_ds structure for microblaze architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _ASM_MICROBLAZE_SHMBUF_H */ diff --git a/arch/microblaze/include/asm/shmparam.h b/arch/microblaze/include/asm/shmparam.h new file mode 100644 index 0000000..9f5fc2b --- /dev/null +++ b/arch/microblaze/include/asm/shmparam.h @@ -0,0 +1,6 @@ +#ifndef _ASM_MICROBLAZE_SHMPARAM_H +#define _ASM_MICROBLAZE_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _ASM_MICROBLAZE_SHMPARAM_H */ diff --git a/arch/microblaze/include/asm/sigcontext.h b/arch/microblaze/include/asm/sigcontext.h new file mode 100644 index 0000000..55873c8 --- /dev/null +++ b/arch/microblaze/include/asm/sigcontext.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SIGCONTEXT_H +#define _ASM_MICROBLAZE_SIGCONTEXT_H + +/* FIXME should be linux/ptrace.h */ +#include <asm/ptrace.h> + +struct sigcontext { + struct pt_regs regs; + unsigned long oldmask; +}; + +#endif /* _ASM_MICROBLAZE_SIGCONTEXT_H */ diff --git a/arch/microblaze/include/asm/siginfo.h b/arch/microblaze/include/asm/siginfo.h new file mode 100644 index 0000000..f162911 --- /dev/null +++ b/arch/microblaze/include/asm/siginfo.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SIGINFO_H +#define _ASM_MICROBLAZE_SIGINFO_H + +#include <linux/types.h> +#include <asm-generic/siginfo.h> + +#endif /* _ASM_MICROBLAZE_SIGINFO_H */ diff --git a/arch/microblaze/include/asm/signal.h b/arch/microblaze/include/asm/signal.h new file mode 100644 index 0000000..9676fad --- /dev/null +++ b/arch/microblaze/include/asm/signal.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * Yasushi SHOJI <yashi@atmark-techno.com> + * Tetsuya OHKAWA <tetsuya@atmark-techno.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SIGNAL_H +#define _ASM_MICROBLAZE_SIGNAL_H + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +#define SA_RESTORER 0x04000000 + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +# ifndef __ASSEMBLY__ +# include <linux/types.h> +# include <asm-generic/signal.h> + +/* Avoid too many header ordering problems. */ +struct siginfo; + +# ifdef __KERNEL__ +/* + * Most things should be clean enough to redefine this at will, if care + * is taken to make libc match. + */ +# define _NSIG 64 +# define _NSIG_BPW 32 +# define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; + +# include <asm/sigcontext.h> +# undef __HAVE_ARCH_SIG_BITOPS + +# define ptrace_signal_deliver(regs, cookie) do { } while (0) + +# else /* !__KERNEL__ */ + +/* Here we must cater to libcs that poke about in kernel headers. */ + +# define NSIG 32 +typedef unsigned long sigset_t; + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +# define sa_handler _u._sa_handler +# define sa_sigaction _u._sa_sigaction + +# endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +# endif /* __ASSEMBLY__ */ +#endif /* _ASM_MICROBLAZE_SIGNAL_H */ diff --git a/arch/microblaze/include/asm/socket.h b/arch/microblaze/include/asm/socket.h new file mode 100644 index 0000000..8259368 --- /dev/null +++ b/arch/microblaze/include/asm/socket.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SOCKET_H +#define _ASM_MICROBLAZE_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockoptions(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_SNDBUFFORCE 32 +#define SO_RCVBUFFORCE 33 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 + +#define SO_PEERSEC 31 +#define SO_PASSSEC 34 + +#define SO_TIMESTAMPNS 35 +#define SCM_TIMESTAMPNS SO_TIMESTAMPNS + +#define SO_MARK 36 + +#define SO_TIMESTAMPING 37 +#define SCM_TIMESTAMPING SO_TIMESTAMPING + +#endif /* _ASM_MICROBLAZE_SOCKET_H */ diff --git a/arch/microblaze/include/asm/sockios.h b/arch/microblaze/include/asm/sockios.h new file mode 100644 index 0000000..9fff57a --- /dev/null +++ b/arch/microblaze/include/asm/sockios.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SOCKIOS_H +#define _ASM_MICROBLAZE_SOCKIOS_H + +#include <linux/ioctl.h> + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ +#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + +#endif /* _ASM_MICROBLAZE_SOCKIOS_H */ diff --git a/arch/microblaze/include/asm/stat.h b/arch/microblaze/include/asm/stat.h new file mode 100644 index 0000000..5f18b8a --- /dev/null +++ b/arch/microblaze/include/asm/stat.h @@ -0,0 +1,73 @@ +/* + * Microblaze stat structure + * + * Copyright (C) 2001,02,03 NEC Electronics Corporation + * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + * + * Written by Miles Bader <miles@gnu.org> + */ + +#ifndef _ASM_MICROBLAZE_STAT_H +#define _ASM_MICROBLAZE_STAT_H + +#include <linux/posix_types.h> + +struct stat { + unsigned int st_dev; + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_rdev; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; /* unsigned long st_atime_nsec */ + unsigned long st_mtime; + unsigned long __unused2; /* unsigned long st_mtime_nsec */ + unsigned long st_ctime; + unsigned long __unused3; /* unsigned long st_ctime_nsec */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct stat64 { + unsigned long long st_dev; + unsigned long __unused1; + + unsigned long long st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned int st_uid; + unsigned int st_gid; + + unsigned long long st_rdev; + unsigned long __unused3; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* No. of 512-byte blocks allocated */ + unsigned long __unused4; /* future possible st_blocks high bits */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned long st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; + + unsigned long __unused8; +}; + +#endif /* _ASM_MICROBLAZE_STAT_H */ diff --git a/arch/microblaze/include/asm/statfs.h b/arch/microblaze/include/asm/statfs.h new file mode 100644 index 0000000..0b91fe1 --- /dev/null +++ b/arch/microblaze/include/asm/statfs.h @@ -0,0 +1 @@ +#include <asm-generic/statfs.h> diff --git a/arch/microblaze/include/asm/string.h b/arch/microblaze/include/asm/string.h new file mode 100644 index 0000000..f7728c9 --- /dev/null +++ b/arch/microblaze/include/asm/string.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_STRING_H +#define _ASM_MICROBLAZE_STRING_H + +#ifndef __KERNEL__ + +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMMOVE + +extern void *memset(void *, int, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t); + +#endif /* __KERNEL__ */ + +#endif /* _ASM_MICROBLAZE_STRING_H */ diff --git a/arch/microblaze/include/asm/swab.h b/arch/microblaze/include/asm/swab.h new file mode 100644 index 0000000..b375d7b --- /dev/null +++ b/arch/microblaze/include/asm/swab.h @@ -0,0 +1,8 @@ +#ifndef _ASM_MICROBLAZE_SWAB_H +#define _ASM_MICROBLAZE_SWAB_H + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) +#define __SWAB_64_THRU_32__ +#endif + +#endif /* _ASM_MICROBLAZE_SWAB_H */ diff --git a/arch/microblaze/include/asm/syscalls.h b/arch/microblaze/include/asm/syscalls.h new file mode 100644 index 0000000..9cb4ff0 --- /dev/null +++ b/arch/microblaze/include/asm/syscalls.h @@ -0,0 +1,45 @@ +#ifndef __ASM_MICROBLAZE_SYSCALLS_H +#define __ASM_MICROBLAZE_SYSCALLS_H +#ifdef __KERNEL__ + +#include <linux/compiler.h> +#include <linux/linkage.h> +#include <linux/types.h> +#include <linux/signal.h> + +/* FIXME will be removed */ +asmlinkage int sys_ipc(uint call, int first, int second, + int third, void *ptr, long fifth); + +struct pt_regs; +asmlinkage int sys_vfork(struct pt_regs *regs); +asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs); +asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv, + char __user *__user *envp, struct pt_regs *regs); + +asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); + +asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, off_t offset); + +/* from signal.c */ +asmlinkage int sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs); + +asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, + struct pt_regs *regs); + +asmlinkage int sys_sigaction(int sig, const struct old_sigaction *act, + struct old_sigaction *oact); + +asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, + struct pt_regs *regs); + +asmlinkage int sys_sigreturn(struct pt_regs *regs); + +asmlinkage int sys_rt_sigreturn(struct pt_regs *regs); + +#endif /* __KERNEL__ */ +#endif /* __ASM_MICROBLAZE_SYSCALLS_H */ diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h new file mode 100644 index 0000000..c4e3088 --- /dev/null +++ b/arch/microblaze/include/asm/system.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_SYSTEM_H +#define _ASM_MICROBLAZE_SYSTEM_H + +#include <asm/registers.h> +#include <asm/setup.h> +#include <asm/irqflags.h> + +struct task_struct; +struct thread_info; + +extern struct task_struct *_switch_to(struct thread_info *prev, + struct thread_info *next); + +#define switch_to(prev, next, last) \ + do { \ + (last) = _switch_to(task_thread_info(prev), \ + task_thread_info(next)); \ + } while (0) + +#define smp_read_barrier_depends() do {} while (0) +#define read_barrier_depends() do {} while (0) + +#define nop() asm volatile ("nop") +#define mb() barrier() +#define rmb() mb() +#define wmb() mb() +#define set_mb(var, value) do { var = value; mb(); } while (0) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() + +void show_trace(struct task_struct *task, unsigned long *stack); +void __bad_xchg(volatile void *ptr, int size); + +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, + int size) +{ + unsigned long ret; + unsigned long flags; + + switch (size) { + case 1: + local_irq_save(flags); + ret = *(volatile unsigned char *)ptr; + *(volatile unsigned char *)ptr = x; + local_irq_restore(flags); + break; + + case 4: + local_irq_save(flags); + ret = *(volatile unsigned long *)ptr; + *(volatile unsigned long *)ptr = x; + local_irq_restore(flags); + break; + default: + __bad_xchg(ptr, size), ret = 0; + break; + } + + return ret; +} + +void disable_hlt(void); +void enable_hlt(void); +void default_idle(void); + +#define xchg(ptr, x) \ + ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) + +void free_init_pages(char *what, unsigned long begin, unsigned long end); +void free_initmem(void); +extern char *klimit; +extern void ret_from_fork(void); + +#ifdef CONFIG_DEBUG_FS +extern struct dentry *of_debugfs_root; +#endif + +#define arch_align_stack(x) (x) + +#endif /* _ASM_MICROBLAZE_SYSTEM_H */ diff --git a/arch/microblaze/include/asm/termbits.h b/arch/microblaze/include/asm/termbits.h new file mode 100644 index 0000000..a1b64bc --- /dev/null +++ b/arch/microblaze/include/asm/termbits.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_TERMBITS_H +#define _ASM_MICROBLAZE_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ + +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ + +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ + +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ + +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define BOTHER 0010000 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + +/* c_lflag bits */ + +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* tcflow() and TCXONC use these */ + +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ + +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ + +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* _ASM_MICROBLAZE_TERMBITS_H */ diff --git a/arch/microblaze/include/asm/termios.h b/arch/microblaze/include/asm/termios.h new file mode 100644 index 0000000..102d772 --- /dev/null +++ b/arch/microblaze/include/asm/termios.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_TERMIOS_H +#define _ASM_MICROBLAZE_TERMIOS_H + +#include <linux/string.h> +#include <asm/termbits.h> +#include <asm/ioctls.h> + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* Modem lines */ + +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +/* Line disciplines */ + +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 +#define N_X25 6 /* X.25 async */ +#define N_6PACK 7 +#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */ +#define N_R3964 9 /* Reserved for Simatic R3964 module */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */ +#define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */ +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards + about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 +#define N_HCI 15 /* Bluetooth HCI UART */ + +#ifdef __KERNEL__ + +#include <asm-generic/termios.h> + +#endif /* __KERNEL__ */ + +#endif /* _ASM_MICROBLAZE_TERMIOS_H */ diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h new file mode 100644 index 0000000..4c3943e --- /dev/null +++ b/arch/microblaze/include/asm/thread_info.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_THREAD_INFO_H +#define _ASM_MICROBLAZE_THREAD_INFO_H + +#ifdef __KERNEL__ + +/* we have 8k stack */ +#define THREAD_SHIFT 13 +#define THREAD_SIZE (1 << THREAD_SHIFT) +#define THREAD_SIZE_ORDER 1 + +#ifndef __ASSEMBLY__ +# include <linux/types.h> +# include <asm/processor.h> +# include <asm/segment.h> + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants + * must also be changed + */ + +struct cpu_context { + __u32 r1; /* stack pointer */ + __u32 r2; + /* dedicated registers */ + __u32 r13; + __u32 r14; + __u32 r15; + __u32 r16; + __u32 r17; + __u32 r18; + /* non-volatile registers */ + __u32 r19; + __u32 r20; + __u32 r21; + __u32 r22; + __u32 r23; + __u32 r24; + __u32 r25; + __u32 r26; + __u32 r27; + __u32 r28; + __u32 r29; + __u32 r30; + /* r31 is used as current task pointer */ + /* special purpose registers */ + __u32 msr; + __u32 ear; + __u32 esr; + __u32 fsr; +}; + +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + unsigned long status; /* thread-synchronous flags */ + __u32 cpu; /* current CPU */ + __s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/ + mm_segment_t addr_limit; /* thread address space */ + struct restart_block restart_block; + + struct cpu_context cpu_context; +}; + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* how to get the thread information struct from C */ +static inline struct thread_info *current_thread_info(void) +{ + register unsigned long sp asm("r1"); + + return (struct thread_info *)(sp & ~(THREAD_SIZE-1)); +} + +/* thread information allocation */ +#endif /* __ASSEMBLY__ */ + +#define PREEMPT_ACTIVE 0x10000000 + +/* + * thread information flags + * - these are process state flags that various assembly files may + * need to access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +/* restore singlestep on return to user mode */ +#define TIF_SINGLESTEP 4 +#define TIF_IRET 5 /* return with iret */ +#define TIF_MEMDIE 6 +#define TIF_FREEZE 14 /* Freezing for suspend */ + +/* FIXME change in entry.S */ +#define TIF_KERNEL_TRACE 8 /* kernel trace active */ + +/* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_POLLING_NRFLAG 16 + +#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) +#define _TIF_IRET (1<<TIF_IRET) +#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) +#define _TIF_FREEZE (1<<TIF_FREEZE) +#define _TIF_KERNEL_TRACE (1 << TIF_KERNEL_TRACE) + +/* work to do on interrupt/exception return */ +#define _TIF_WORK_MASK 0x0000FFFE +/* work to do on any return to u-space */ +#define _TIF_ALLWORK_MASK 0x0000FFFF + +/* + * Thread-synchronous status. + * + * This is different from the flags in that nobody else + * ever touches our thread-synchronous status, so we don't + * have to worry about atomic accesses. + */ +/* FPU was used by this task this quantum (SMP) */ +#define TS_USEDFPU 0x0001 + +#endif /* __KERNEL__ */ +#endif /* _ASM_MICROBLAZE_THREAD_INFO_H */ diff --git a/arch/microblaze/include/asm/timex.h b/arch/microblaze/include/asm/timex.h new file mode 100644 index 0000000..678525d --- /dev/null +++ b/arch/microblaze/include/asm/timex.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_TIMEX_H +#define _ASM_MICROBLAZE_TIMEX_H + +#define CLOCK_TICK_RATE 1000 /* Timer input freq. */ + +typedef unsigned long cycles_t; + +#define get_cycles() (0) + +#endif /* _ASM_TIMEX_H */ diff --git a/arch/microblaze/include/asm/tlb.h b/arch/microblaze/include/asm/tlb.h new file mode 100644 index 0000000..d1dfe37 --- /dev/null +++ b/arch/microblaze/include/asm/tlb.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_TLB_H +#define _ASM_MICROBLAZE_TLB_H + +#define tlb_flush(tlb) do {} while (0) + +#include <asm-generic/tlb.h> + +#endif /* _ASM_MICROBLAZE_TLB_H */ diff --git a/arch/microblaze/include/asm/tlbflush.h b/arch/microblaze/include/asm/tlbflush.h new file mode 100644 index 0000000..d7fe762 --- /dev/null +++ b/arch/microblaze/include/asm/tlbflush.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_TLBFLUSH_H +#define _ASM_MICROBLAZE_TLBFLUSH_H + +#define flush_tlb() BUG() +#define flush_tlb_all() BUG() +#define flush_tlb_mm(mm) BUG() +#define flush_tlb_page(vma, addr) BUG() +#define flush_tlb_range(mm, start, end) BUG() +#define flush_tlb_pgtables(mm, start, end) BUG() +#define flush_tlb_kernel_range(start, end) BUG() + +#endif /* _ASM_MICROBLAZE_TLBFLUSH_H */ diff --git a/arch/microblaze/include/asm/topology.h b/arch/microblaze/include/asm/topology.h new file mode 100644 index 0000000..96bcea5 --- /dev/null +++ b/arch/microblaze/include/asm/topology.h @@ -0,0 +1,11 @@ +#include <asm-generic/topology.h> + +#ifndef _ASM_MICROBLAZE_TOPOLOGY_H +#define _ASM_MICROBLAZE_TOPOLOGY_H + +struct device_node; +static inline int of_node_to_nid(struct device_node *device) +{ + return 0; +} +#endif /* _ASM_MICROBLAZE_TOPOLOGY_H */ diff --git a/arch/microblaze/include/asm/types.h b/arch/microblaze/include/asm/types.h new file mode 100644 index 0000000..bebc018 --- /dev/null +++ b/arch/microblaze/include/asm/types.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_TYPES_H +#define _ASM_MICROBLAZE_TYPES_H + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ + +#include <asm-generic/int-ll64.h> + +# ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +# ifdef __KERNEL__ +# define BITS_PER_LONG 32 + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +# endif/* __KERNEL__ */ +# endif /* __ASSEMBLY__ */ +#endif /* _ASM_MICROBLAZE_TYPES_H */ diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h new file mode 100644 index 0000000..5a3ffc3 --- /dev/null +++ b/arch/microblaze/include/asm/uaccess.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_UACCESS_H +#define _ASM_MICROBLAZE_UACCESS_H + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/sched.h> /* RLIMIT_FSIZE */ +#include <linux/mm.h> + +#include <asm/mmu.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/segment.h> +#include <linux/string.h> + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +extern int ___range_ok(unsigned long addr, unsigned long size); + +#define __range_ok(addr, size) \ + ___range_ok((unsigned long)(addr), (unsigned long)(size)) + +#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) +#define __access_ok(add, size) (__range_ok((addr), (size)) == 0) + +extern inline int bad_user_access_length(void) +{ + return 0; +} +/* FIXME this is function for optimalization -> memcpy */ +#define __get_user(var, ptr) \ + ({ \ + int __gu_err = 0; \ + switch (sizeof(*(ptr))) { \ + case 1: \ + case 2: \ + case 4: \ + (var) = *(ptr); \ + break; \ + case 8: \ + memcpy((void *) &(var), (ptr), 8); \ + break; \ + default: \ + (var) = 0; \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + __gu_err; \ + }) + +#define __get_user_bad() (bad_user_access_length(), (-EFAULT)) + +#define __put_user(var, ptr) \ + ({ \ + int __pu_err = 0; \ + switch (sizeof(*(ptr))) { \ + case 1: \ + case 2: \ + case 4: \ + *(ptr) = (var); \ + break; \ + case 8: { \ + typeof(*(ptr)) __pu_val = var; \ + memcpy(ptr, &__pu_val, sizeof(__pu_val));\ + } \ + break; \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ + }) + +#define __put_user_bad() (bad_user_access_length(), (-EFAULT)) + +#define put_user(x, ptr) __put_user(x, ptr) +#define get_user(x, ptr) __get_user(x, ptr) + +#define copy_to_user(to, from, n) (memcpy(to, from, n), 0) +#define copy_from_user(to, from, n) (memcpy(to, from, n), 0) + +#define __copy_to_user(to, from, n) (copy_to_user(to, from, n)) +#define __copy_from_user(to, from, n) (copy_from_user(to, from, n)) +#define __copy_to_user_inatomic(to, from, n) (__copy_to_user(to, from, n)) +#define __copy_from_user_inatomic(to, from, n) (__copy_from_user(to, from, n)) + +#define __clear_user(addr, n) (memset((void *)addr, 0, n), 0) + +static inline unsigned long clear_user(void *addr, unsigned long size) +{ + if (access_ok(VERIFY_WRITE, addr, size)) + size = __clear_user(addr, size); + return size; +} + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + + +extern long strncpy_from_user(char *dst, const char __user *src, long count); +extern long strnlen_user(const char __user *src, long count); +extern long __strncpy_from_user(char *dst, const char __user *src, long count); + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ +struct exception_table_entry { + unsigned long insn, fixup; +}; + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ + +#endif /* _ASM_MICROBLAZE_UACCESS_H */ diff --git a/arch/microblaze/include/asm/ucontext.h b/arch/microblaze/include/asm/ucontext.h new file mode 100644 index 0000000..11f6bb3 --- /dev/null +++ b/arch/microblaze/include/asm/ucontext.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_UCONTEXT_H +#define _ASM_MICROBLAZE_UCONTEXT_H + +#include <asm/sigcontext.h> + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif /* _ASM_MICROBLAZE_UCONTEXT_H */ diff --git a/arch/microblaze/include/asm/unaligned.h b/arch/microblaze/include/asm/unaligned.h new file mode 100644 index 0000000..9d66b64 --- /dev/null +++ b/arch/microblaze/include/asm/unaligned.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2008 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_UNALIGNED_H +#define _ASM_MICROBLAZE_UNALIGNED_H + +# ifdef __KERNEL__ + +# include <linux/unaligned/access_ok.h> +# include <linux/unaligned/generic.h> + +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be + +# endif /* __KERNEL__ */ +#endif /* _ASM_MICROBLAZE_UNALIGNED_H */ diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h new file mode 100644 index 0000000..d9d3903 --- /dev/null +++ b/arch/microblaze/include/asm/unistd.h @@ -0,0 +1,421 @@ +/* + * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_UNISTD_H +#define _ASM_MICROBLAZE_UNISTD_H + +#define __NR_restart_syscall 0 /* ok */ +#define __NR_exit 1 /* ok */ +#define __NR_fork 2 /* not for no MMU - weird */ +#define __NR_read 3 /* ok */ +#define __NR_write 4 /* ok */ +#define __NR_open 5 /* openat */ +#define __NR_close 6 /* ok */ +#define __NR_waitpid 7 /* waitid */ +#define __NR_creat 8 /* openat */ +#define __NR_link 9 /* linkat */ +#define __NR_unlink 10 /* unlinkat */ +#define __NR_execve 11 /* ok */ +#define __NR_chdir 12 /* ok */ +#define __NR_time 13 /* obsolete -> sys_gettimeofday */ +#define __NR_mknod 14 /* mknodat */ +#define __NR_chmod 15 /* fchmodat */ +#define __NR_lchown 16 /* ok */ +#define __NR_break 17 /* don't know */ +#define __NR_oldstat 18 /* remove */ +#define __NR_lseek 19 /* ok */ +#define __NR_getpid 20 /* ok */ +#define __NR_mount 21 /* ok */ +#define __NR_umount 22 /* ok */ /* use only umount2 */ +#define __NR_setuid 23 /* ok */ +#define __NR_getuid 24 /* ok */ +#define __NR_stime 25 /* obsolete -> sys_settimeofday */ +#define __NR_ptrace 26 /* ok */ +#define __NR_alarm 27 /* obsolete -> sys_setitimer */ +#define __NR_oldfstat 28 /* remove */ +#define __NR_pause 29 /* obsolete -> sys_rt_sigtimedwait */ +#define __NR_utime 30 /* obsolete -> sys_utimesat */ +#define __NR_stty 31 /* remove */ +#define __NR_gtty 32 /* remove */ +#define __NR_access 33 /* faccessat */ +/* can be implemented by sys_setpriority */ +#define __NR_nice 34 +#define __NR_ftime 35 /* remove */ +#define __NR_sync 36 /* ok */ +#define __NR_kill 37 /* ok */ +#define __NR_rename 38 /* renameat */ +#define __NR_mkdir 39 /* mkdirat */ +#define __NR_rmdir 40 /* unlinkat */ +#define __NR_dup 41 /* ok */ +#define __NR_pipe 42 /* ok */ +#define __NR_times 43 /* ok */ +#define __NR_prof 44 /* remove */ +#define __NR_brk 45 /* ok -mmu, nommu specific */ +#define __NR_setgid 46 /* ok */ +#define __NR_getgid 47 /* ok */ +#define __NR_signal 48 /* obsolete -> sys_rt_sigaction */ +#define __NR_geteuid 49 /* ok */ +#define __NR_getegid 50 /* ok */ +#define __NR_acct 51 /* add it and then I can disable it */ +#define __NR_umount2 52 /* remove */ +#define __NR_lock 53 /* remove */ +#define __NR_ioctl 54 /* ok */ +#define __NR_fcntl 55 /* ok -> 64bit version*/ +#define __NR_mpx 56 /* remove */ +#define __NR_setpgid 57 /* ok */ +#define __NR_ulimit 58 /* remove */ +#define __NR_oldolduname 59 /* remove */ +#define __NR_umask 60 /* ok */ +#define __NR_chroot 61 /* ok */ +#define __NR_ustat 62 /* obsolete -> statfs64 */ +#define __NR_dup2 63 /* ok */ +#define __NR_getppid 64 /* ok */ +#define __NR_getpgrp 65 /* obsolete -> sys_getpgid */ +#define __NR_setsid 66 /* ok */ +#define __NR_sigaction 67 /* obsolete -> rt_sigaction */ +#define __NR_sgetmask 68 /* obsolete -> sys_rt_sigprocmask */ +#define __NR_ssetmask 69 /* obsolete ->sys_rt_sigprocmask */ +#define __NR_setreuid 70 /* ok */ +#define __NR_setregid 71 /* ok */ +#define __NR_sigsuspend 72 /* obsolete -> rt_sigsuspend */ +#define __NR_sigpending 73 /* obsolete -> sys_rt_sigpending */ +#define __NR_sethostname 74 /* ok */ +#define __NR_setrlimit 75 /* ok */ +#define __NR_getrlimit 76 /* ok Back compatible 2G limited rlimit */ +#define __NR_getrusage 77 /* ok */ +#define __NR_gettimeofday 78 /* ok */ +#define __NR_settimeofday 79 /* ok */ +#define __NR_getgroups 80 /* ok */ +#define __NR_setgroups 81 /* ok */ +#define __NR_select 82 /* obsolete -> sys_pselect7 */ +#define __NR_symlink 83 /* symlinkat */ +#define __NR_oldlstat 84 /* remove */ +#define __NR_readlink 85 /* obsolete -> sys_readlinkat */ +#define __NR_uselib 86 /* remove */ +#define __NR_swapon 87 /* ok */ +#define __NR_reboot 88 /* ok */ +#define __NR_readdir 89 /* remove ? */ +#define __NR_mmap 90 /* obsolete -> sys_mmap2 */ +#define __NR_munmap 91 /* ok - mmu and nommu */ +#define __NR_truncate 92 /* ok or truncate64 */ +#define __NR_ftruncate 93 /* ok or ftruncate64 */ +#define __NR_fchmod 94 /* ok */ +#define __NR_fchown 95 /* ok */ +#define __NR_getpriority 96 /* ok */ +#define __NR_setpriority 97 /* ok */ +#define __NR_profil 98 /* remove */ +#define __NR_statfs 99 /* ok or statfs64 */ +#define __NR_fstatfs 100 /* ok or fstatfs64 */ +#define __NR_ioperm 101 /* remove */ +#define __NR_socketcall 102 /* remove */ +#define __NR_syslog 103 /* ok */ +#define __NR_setitimer 104 /* ok */ +#define __NR_getitimer 105 /* ok */ +#define __NR_stat 106 /* remove */ +#define __NR_lstat 107 /* remove */ +#define __NR_fstat 108 /* remove */ +#define __NR_olduname 109 /* remove */ +#define __NR_iopl 110 /* remove */ +#define __NR_vhangup 111 /* ok */ +#define __NR_idle 112 /* remove */ +#define __NR_vm86old 113 /* remove */ +#define __NR_wait4 114 /* obsolete -> waitid */ +#define __NR_swapoff 115 /* ok */ +#define __NR_sysinfo 116 /* ok */ +#define __NR_ipc 117 /* remove - direct call */ +#define __NR_fsync 118 /* ok */ +#define __NR_sigreturn 119 /* obsolete -> sys_rt_sigreturn */ +#define __NR_clone 120 /* ok */ +#define __NR_setdomainname 121 /* ok */ +#define __NR_uname 122 /* remove */ +#define __NR_modify_ldt 123 /* remove */ +#define __NR_adjtimex 124 /* ok */ +#define __NR_mprotect 125 /* remove */ +#define __NR_sigprocmask 126 /* obsolete -> sys_rt_sigprocmask */ +#define __NR_create_module 127 /* remove */ +#define __NR_init_module 128 /* ok */ +#define __NR_delete_module 129 /* ok */ +#define __NR_get_kernel_syms 130 /* remove */ +#define __NR_quotactl 131 /* ok */ +#define __NR_getpgid 132 /* ok */ +#define __NR_fchdir 133 /* ok */ +#define __NR_bdflush 134 /* remove */ +#define __NR_sysfs 135 /* needed for busybox */ +#define __NR_personality 136 /* ok */ +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 /* ok */ +#define __NR_setfsgid 139 /* ok */ +#define __NR__llseek 140 /* remove only lseek */ +#define __NR_getdents 141 /* ok or getdents64 */ +#define __NR__newselect 142 /* remove */ +#define __NR_flock 143 /* ok */ +#define __NR_msync 144 /* remove */ +#define __NR_readv 145 /* ok */ +#define __NR_writev 146 /* ok */ +#define __NR_getsid 147 /* ok */ +#define __NR_fdatasync 148 /* ok */ +#define __NR__sysctl 149 /* remove */ +#define __NR_mlock 150 /* ok - nommu or mmu */ +#define __NR_munlock 151 /* ok - nommu or mmu */ +#define __NR_mlockall 152 /* ok - nommu or mmu */ +#define __NR_munlockall 153 /* ok - nommu or mmu */ +#define __NR_sched_setparam 154 /* ok */ +#define __NR_sched_getparam 155 /* ok */ +#define __NR_sched_setscheduler 156 /* ok */ +#define __NR_sched_getscheduler 157 /* ok */ +#define __NR_sched_yield 158 /* ok */ +#define __NR_sched_get_priority_max 159 /* ok */ +#define __NR_sched_get_priority_min 160 /* ok */ +#define __NR_sched_rr_get_interval 161 /* ok */ +#define __NR_nanosleep 162 /* ok */ +#define __NR_mremap 163 /* ok - nommu or mmu */ +#define __NR_setresuid 164 /* ok */ +#define __NR_getresuid 165 /* ok */ +#define __NR_vm86 166 /* remove */ +#define __NR_query_module 167 /* ok */ +#define __NR_poll 168 /* obsolete -> sys_ppoll */ +#define __NR_nfsservctl 169 /* ok */ +#define __NR_setresgid 170 /* ok */ +#define __NR_getresgid 171 /* ok */ +#define __NR_prctl 172 /* ok */ +#define __NR_rt_sigreturn 173 /* ok */ +#define __NR_rt_sigaction 174 /* ok */ +#define __NR_rt_sigprocmask 175 /* ok */ +#define __NR_rt_sigpending 176 /* ok */ +#define __NR_rt_sigtimedwait 177 /* ok */ +#define __NR_rt_sigqueueinfo 178 /* ok */ +#define __NR_rt_sigsuspend 179 /* ok */ +#define __NR_pread64 180 /* ok */ +#define __NR_pwrite64 181 /* ok */ +#define __NR_chown 182 /* obsolete -> fchownat */ +#define __NR_getcwd 183 /* ok */ +#define __NR_capget 184 /* ok */ +#define __NR_capset 185 /* ok */ +#define __NR_sigaltstack 186 /* remove */ +#define __NR_sendfile 187 /* ok -> exist 64bit version*/ +#define __NR_getpmsg 188 /* remove */ +/* remove - some people actually want streams */ +#define __NR_putpmsg 189 +/* for noMMU - group with clone -> maybe remove */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 /* remove - SuS compliant getrlimit */ +#define __NR_mmap2 192 /* ok */ +#define __NR_truncate64 193 /* ok */ +#define __NR_ftruncate64 194 /* ok */ +#define __NR_stat64 195 /* remove _ARCH_WANT_STAT64 */ +#define __NR_lstat64 196 /* remove _ARCH_WANT_STAT64 */ +#define __NR_fstat64 197 /* remove _ARCH_WANT_STAT64 */ +#define __NR_lchown32 198 /* ok - without 32 */ +#define __NR_getuid32 199 /* ok - without 32 */ +#define __NR_getgid32 200 /* ok - without 32 */ +#define __NR_geteuid32 201 /* ok - without 32 */ +#define __NR_getegid32 202 /* ok - without 32 */ +#define __NR_setreuid32 203 /* ok - without 32 */ +#define __NR_setregid32 204 /* ok - without 32 */ +#define __NR_getgroups32 205 /* ok - without 32 */ +#define __NR_setgroups32 206 /* ok - without 32 */ +#define __NR_fchown32 207 /* ok - without 32 */ +#define __NR_setresuid32 208 /* ok - without 32 */ +#define __NR_getresuid32 209 /* ok - without 32 */ +#define __NR_setresgid32 210 /* ok - without 32 */ +#define __NR_getresgid32 211 /* ok - without 32 */ +#define __NR_chown32 212 /* ok - without 32 -obsolete -> fchownat */ +#define __NR_setuid32 213 /* ok - without 32 */ +#define __NR_setgid32 214 /* ok - without 32 */ +#define __NR_setfsuid32 215 /* ok - without 32 */ +#define __NR_setfsgid32 216 /* ok - without 32 */ +#define __NR_pivot_root 217 /* ok */ +#define __NR_mincore 218 /* ok */ +#define __NR_madvise 219 /* ok */ +#define __NR_getdents64 220 /* ok */ +#define __NR_fcntl64 221 /* ok */ +/* 223 is unused */ +#define __NR_gettid 224 /* ok */ +#define __NR_readahead 225 /* ok */ +#define __NR_setxattr 226 /* ok */ +#define __NR_lsetxattr 227 /* ok */ +#define __NR_fsetxattr 228 /* ok */ +#define __NR_getxattr 229 /* ok */ +#define __NR_lgetxattr 230 /* ok */ +#define __NR_fgetxattr 231 /* ok */ +#define __NR_listxattr 232 /* ok */ +#define __NR_llistxattr 233 /* ok */ +#define __NR_flistxattr 234 /* ok */ +#define __NR_removexattr 235 /* ok */ +#define __NR_lremovexattr 236 /* ok */ +#define __NR_fremovexattr 237 /* ok */ +#define __NR_tkill 238 /* ok */ +#define __NR_sendfile64 239 /* ok */ +#define __NR_futex 240 /* ok */ +#define __NR_sched_setaffinity 241 /* ok */ +#define __NR_sched_getaffinity 242 /* ok */ +#define __NR_set_thread_area 243 /* remove */ +#define __NR_get_thread_area 244 /* remove */ +#define __NR_io_setup 245 /* ok */ +#define __NR_io_destroy 246 /* ok */ +#define __NR_io_getevents 247 /* ok */ +#define __NR_io_submit 248 /* ok */ +#define __NR_io_cancel 249 /* ok */ +#define __NR_fadvise64 250 /* remove -> sys_fadvise64_64 */ +/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */ +#define __NR_exit_group 252 /* ok */ +#define __NR_lookup_dcookie 253 /* ok */ +#define __NR_epoll_create 254 /* ok */ +#define __NR_epoll_ctl 255 /* ok */ +#define __NR_epoll_wait 256 /* obsolete -> sys_epoll_pwait */ +#define __NR_remap_file_pages 257 /* only for mmu */ +#define __NR_set_tid_address 258 /* ok */ +#define __NR_timer_create 259 /* ok */ +#define __NR_timer_settime (__NR_timer_create+1) /* 260 */ /* ok */ +#define __NR_timer_gettime (__NR_timer_create+2) /* 261 */ /* ok */ +#define __NR_timer_getoverrun (__NR_timer_create+3) /* 262 */ /* ok */ +#define __NR_timer_delete (__NR_timer_create+4) /* 263 */ /* ok */ +#define __NR_clock_settime (__NR_timer_create+5) /* 264 */ /* ok */ +#define __NR_clock_gettime (__NR_timer_create+6) /* 265 */ /* ok */ +#define __NR_clock_getres (__NR_timer_create+7) /* 266 */ /* ok */ +#define __NR_clock_nanosleep (__NR_timer_create+8) /* 267 */ /* ok */ +#define __NR_statfs64 268 /* ok */ +#define __NR_fstatfs64 269 /* ok */ +#define __NR_tgkill 270 /* ok */ +#define __NR_utimes 271 /* obsolete -> sys_futimesat */ +#define __NR_fadvise64_64 272 /* ok */ +#define __NR_vserver 273 /* ok */ +#define __NR_mbind 274 /* only for mmu */ +#define __NR_get_mempolicy 275 /* only for mmu */ +#define __NR_set_mempolicy 276 /* only for mmu */ +#define __NR_mq_open 277 /* ok */ +#define __NR_mq_unlink (__NR_mq_open+1) /* 278 */ /* ok */ +#define __NR_mq_timedsend (__NR_mq_open+2) /* 279 */ /* ok */ +#define __NR_mq_timedreceive (__NR_mq_open+3) /* 280 */ /* ok */ +#define __NR_mq_notify (__NR_mq_open+4) /* 281 */ /* ok */ +#define __NR_mq_getsetattr (__NR_mq_open+5) /* 282 */ /* ok */ +#define __NR_kexec_load 283 /* ok */ +#define __NR_waitid 284 /* ok */ +/* #define __NR_sys_setaltroot 285 */ +#define __NR_add_key 286 /* ok */ +#define __NR_request_key 287 /* ok */ +#define __NR_keyctl 288 /* ok */ +#define __NR_ioprio_set 289 /* ok */ +#define __NR_ioprio_get 290 /* ok */ +#define __NR_inotify_init 291 /* ok */ +#define __NR_inotify_add_watch 292 /* ok */ +#define __NR_inotify_rm_watch 293 /* ok */ +#define __NR_migrate_pages 294 /* mmu */ +#define __NR_openat 295 /* ok */ +#define __NR_mkdirat 296 /* ok */ +#define __NR_mknodat 297 /* ok */ +#define __NR_fchownat 298 /* ok */ +#define __NR_futimesat 299 /* obsolete -> sys_utimesat */ +#define __NR_fstatat64 300 /* stat64 */ +#define __NR_unlinkat 301 /* ok */ +#define __NR_renameat 302 /* ok */ +#define __NR_linkat 303 /* ok */ +#define __NR_symlinkat 304 /* ok */ +#define __NR_readlinkat 305 /* ok */ +#define __NR_fchmodat 306 /* ok */ +#define __NR_faccessat 307 /* ok */ +#define __NR_pselect6 308 /* obsolete -> sys_pselect7 */ +#define __NR_ppoll 309 /* ok */ +#define __NR_unshare 310 /* ok */ +#define __NR_set_robust_list 311 /* ok */ +#define __NR_get_robust_list 312 /* ok */ +#define __NR_splice 313 /* ok */ +#define __NR_sync_file_range 314 /* ok */ +#define __NR_tee 315 /* ok */ +#define __NR_vmsplice 316 /* ok */ +#define __NR_move_pages 317 /* mmu */ +#define __NR_getcpu 318 /* ok */ +#define __NR_epoll_pwait 319 /* ok */ +#define __NR_utimensat 320 /* ok */ +#define __NR_signalfd 321 /* ok */ +#define __NR_timerfd_create 322 /* ok */ +#define __NR_eventfd 323 /* ok */ +#define __NR_fallocate 324 /* ok */ +#define __NR_semtimedop 325 /* ok - semaphore group */ +#define __NR_timerfd_settime 326 /* ok */ +#define __NR_timerfd_gettime 327 /* ok */ +/* sysv ipc syscalls */ +#define __NR_semctl 328 /* ok */ +#define __NR_semget 329 /* ok */ +#define __NR_semop 330 /* ok */ +#define __NR_msgctl 331 /* ok */ +#define __NR_msgget 332 /* ok */ +#define __NR_msgrcv 333 /* ok */ +#define __NR_msgsnd 334 /* ok */ +#define __NR_shmat 335 /* ok */ +#define __NR_shmctl 336 /* ok */ +#define __NR_shmdt 337 /* ok */ +#define __NR_shmget 338 /* ok */ + + +#define __NR_signalfd4 339 /* new */ +#define __NR_eventfd2 340 /* new */ +#define __NR_epoll_create1 341 /* new */ +#define __NR_dup3 342 /* new */ +#define __NR_pipe2 343 /* new */ +#define __NR_inotify_init1 344 /* new */ +#define __NR_socket 345 /* new */ +#define __NR_socketpair 346 /* new */ +#define __NR_bind 347 /* new */ +#define __NR_listen 348 /* new */ +#define __NR_accept 349 /* new */ +#define __NR_connect 350 /* new */ +#define __NR_getsockname 351 /* new */ +#define __NR_getpeername 352 /* new */ +#define __NR_sendto 353 /* new */ +#define __NR_send 354 /* new */ +#define __NR_recvfrom 355 /* new */ +#define __NR_recv 356 /* new */ +#define __NR_setsockopt 357 /* new */ +#define __NR_getsockopt 358 /* new */ +#define __NR_shutdown 359 /* new */ +#define __NR_sendmsg 360 /* new */ +#define __NR_recvmsg 361 /* new */ +#define __NR_accept04 362 /* new */ + +#define __NR_syscalls 363 + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +#define __ARCH_WANT_IPC_PARSE_VERSION +/* #define __ARCH_WANT_OLD_READDIR */ +/* #define __ARCH_WANT_OLD_STAT */ +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +/* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */ +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION +/* #define __ARCH_WANT_SYS_RT_SIGSUSPEND */ + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ +#endif /* _ASM_MICROBLAZE_UNISTD_H */ diff --git a/arch/microblaze/include/asm/user.h b/arch/microblaze/include/asm/user.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/arch/microblaze/include/asm/user.h @@ -0,0 +1 @@ + diff --git a/arch/microblaze/include/asm/vga.h b/arch/microblaze/include/asm/vga.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/arch/microblaze/include/asm/vga.h @@ -0,0 +1 @@ + diff --git a/arch/microblaze/include/asm/xor.h b/arch/microblaze/include/asm/xor.h new file mode 100644 index 0000000..c82eb12 --- /dev/null +++ b/arch/microblaze/include/asm/xor.h @@ -0,0 +1 @@ +#include <asm-generic/xor.h> diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile new file mode 100644 index 0000000..da94bec --- /dev/null +++ b/arch/microblaze/kernel/Makefile @@ -0,0 +1,19 @@ +# +# Makefile +# + +extra-y := head.o vmlinux.lds + +obj-y += exceptions.o \ + hw_exception_handler.o init_task.o intc.o irq.o of_device.o \ + of_platform.o process.o prom.o prom_parse.o ptrace.o \ + setup.o signal.o sys_microblaze.o timer.o traps.o + +obj-y += cpu/ + +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_SELFMOD) += selfmod.o +obj-$(CONFIG_HEART_BEAT) += heartbeat.o +obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o + +obj-y += entry$(MMUEXT).o diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c new file mode 100644 index 0000000..38e1a2e --- /dev/null +++ b/arch/microblaze/kernel/asm-offsets.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/stddef.h> +#include <linux/sched.h> +#include <linux/kernel_stat.h> +#include <linux/ptrace.h> +#include <linux/hardirq.h> +#include <linux/thread_info.h> +#include <linux/kbuild.h> + +int main(int argc, char *argv[]) +{ + /* struct pt_regs */ + DEFINE(PT_SIZE, sizeof(struct pt_regs)); + DEFINE(PT_MSR, offsetof(struct pt_regs, msr)); + DEFINE(PT_EAR, offsetof(struct pt_regs, ear)); + DEFINE(PT_ESR, offsetof(struct pt_regs, esr)); + DEFINE(PT_FSR, offsetof(struct pt_regs, fsr)); + DEFINE(PT_PC, offsetof(struct pt_regs, pc)); + DEFINE(PT_R0, offsetof(struct pt_regs, r0)); + DEFINE(PT_R1, offsetof(struct pt_regs, r1)); + DEFINE(PT_R2, offsetof(struct pt_regs, r2)); + DEFINE(PT_R3, offsetof(struct pt_regs, r3)); + DEFINE(PT_R4, offsetof(struct pt_regs, r4)); + DEFINE(PT_R5, offsetof(struct pt_regs, r5)); + DEFINE(PT_R6, offsetof(struct pt_regs, r6)); + DEFINE(PT_R7, offsetof(struct pt_regs, r7)); + DEFINE(PT_R8, offsetof(struct pt_regs, r8)); + DEFINE(PT_R9, offsetof(struct pt_regs, r9)); + DEFINE(PT_R10, offsetof(struct pt_regs, r10)); + DEFINE(PT_R11, offsetof(struct pt_regs, r11)); + DEFINE(PT_R12, offsetof(struct pt_regs, r12)); + DEFINE(PT_R13, offsetof(struct pt_regs, r13)); + DEFINE(PT_R14, offsetof(struct pt_regs, r14)); + DEFINE(PT_R15, offsetof(struct pt_regs, r15)); + DEFINE(PT_R16, offsetof(struct pt_regs, r16)); + DEFINE(PT_R17, offsetof(struct pt_regs, r17)); + DEFINE(PT_R18, offsetof(struct pt_regs, r18)); + DEFINE(PT_R19, offsetof(struct pt_regs, r19)); + DEFINE(PT_R20, offsetof(struct pt_regs, r20)); + DEFINE(PT_R21, offsetof(struct pt_regs, r21)); + DEFINE(PT_R22, offsetof(struct pt_regs, r22)); + DEFINE(PT_R23, offsetof(struct pt_regs, r23)); + DEFINE(PT_R24, offsetof(struct pt_regs, r24)); + DEFINE(PT_R25, offsetof(struct pt_regs, r25)); + DEFINE(PT_R26, offsetof(struct pt_regs, r26)); + DEFINE(PT_R27, offsetof(struct pt_regs, r27)); + DEFINE(PT_R28, offsetof(struct pt_regs, r28)); + DEFINE(PT_R29, offsetof(struct pt_regs, r29)); + DEFINE(PT_R30, offsetof(struct pt_regs, r30)); + DEFINE(PT_R31, offsetof(struct pt_regs, r31)); + DEFINE(PT_MODE, offsetof(struct pt_regs, kernel_mode)); + BLANK(); + + /* Magic offsets for PTRACE PEEK/POKE etc */ + DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs) + 1); + DEFINE(PT_TEXT_LEN, sizeof(struct pt_regs) + 2); + DEFINE(PT_DATA_ADDR, sizeof(struct pt_regs) + 3); + BLANK(); + + /* struct task_struct */ + DEFINE(TS_THREAD_INFO, offsetof(struct task_struct, stack)); + + /* struct thread_info */ + DEFINE(TI_TASK, offsetof(struct thread_info, task)); + DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); + DEFINE(TI_STATUS, offsetof(struct thread_info, status)); + DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); + DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); + DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); + DEFINE(TI_RESTART_BLOCK, offsetof(struct thread_info, restart_block)); + DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context)); + BLANK(); + + /* struct cpu_context */ + DEFINE(CC_R1, offsetof(struct cpu_context, r1)); /* r1 */ + DEFINE(CC_R2, offsetof(struct cpu_context, r2)); + /* dedicated registers */ + DEFINE(CC_R13, offsetof(struct cpu_context, r13)); + DEFINE(CC_R14, offsetof(struct cpu_context, r14)); + DEFINE(CC_R15, offsetof(struct cpu_context, r15)); + DEFINE(CC_R16, offsetof(struct cpu_context, r16)); + DEFINE(CC_R17, offsetof(struct cpu_context, r17)); + DEFINE(CC_R18, offsetof(struct cpu_context, r18)); + /* non-volatile registers */ + DEFINE(CC_R19, offsetof(struct cpu_context, r19)); + DEFINE(CC_R20, offsetof(struct cpu_context, r20)); + DEFINE(CC_R21, offsetof(struct cpu_context, r21)); + DEFINE(CC_R22, offsetof(struct cpu_context, r22)); + DEFINE(CC_R23, offsetof(struct cpu_context, r23)); + DEFINE(CC_R24, offsetof(struct cpu_context, r24)); + DEFINE(CC_R25, offsetof(struct cpu_context, r25)); + DEFINE(CC_R26, offsetof(struct cpu_context, r26)); + DEFINE(CC_R27, offsetof(struct cpu_context, r27)); + DEFINE(CC_R28, offsetof(struct cpu_context, r28)); + DEFINE(CC_R29, offsetof(struct cpu_context, r29)); + DEFINE(CC_R30, offsetof(struct cpu_context, r30)); + /* special purpose registers */ + DEFINE(CC_MSR, offsetof(struct cpu_context, msr)); + DEFINE(CC_EAR, offsetof(struct cpu_context, ear)); + DEFINE(CC_ESR, offsetof(struct cpu_context, esr)); + DEFINE(CC_FSR, offsetof(struct cpu_context, fsr)); + BLANK(); + + return 0; +} diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile new file mode 100644 index 0000000..20646e5 --- /dev/null +++ b/arch/microblaze/kernel/cpu/Makefile @@ -0,0 +1,8 @@ +# +# Build the appropriate CPU version support +# + +EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \ + -DCPU_REV=$(CPU_REV) + +obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c new file mode 100644 index 0000000..be9fecc --- /dev/null +++ b/arch/microblaze/kernel/cpu/cache.c @@ -0,0 +1,258 @@ +/* + * Cache control for MicroBlaze cache memories + * + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#include <asm/cacheflush.h> +#include <linux/cache.h> +#include <asm/cpuinfo.h> + +/* Exported functions */ + +void _enable_icache(void) +{ + if (cpuinfo.use_icache) { +#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR + __asm__ __volatile__ (" \ + msrset r0, %0; \ + nop; " \ + : \ + : "i" (MSR_ICE) \ + : "memory"); +#else + __asm__ __volatile__ (" \ + mfs r12, rmsr; \ + nop; \ + ori r12, r12, %0; \ + mts rmsr, r12; \ + nop; " \ + : \ + : "i" (MSR_ICE) \ + : "memory", "r12"); +#endif + } +} + +void _disable_icache(void) +{ + if (cpuinfo.use_icache) { +#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR + __asm__ __volatile__ (" \ + msrclr r0, %0; \ + nop; " \ + : \ + : "i" (MSR_ICE) \ + : "memory"); +#else + __asm__ __volatile__ (" \ + mfs r12, rmsr; \ + nop; \ + andi r12, r12, ~%0; \ + mts rmsr, r12; \ + nop; " \ + : \ + : "i" (MSR_ICE) \ + : "memory", "r12"); +#endif + } +} + +void _invalidate_icache(unsigned int addr) +{ + if (cpuinfo.use_icache) { + __asm__ __volatile__ (" \ + wic %0, r0" \ + : \ + : "r" (addr)); + } +} + +void _enable_dcache(void) +{ + if (cpuinfo.use_dcache) { +#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR + __asm__ __volatile__ (" \ + msrset r0, %0; \ + nop; " \ + : \ + : "i" (MSR_DCE) \ + : "memory"); +#else + __asm__ __volatile__ (" \ + mfs r12, rmsr; \ + nop; \ + ori r12, r12, %0; \ + mts rmsr, r12; \ + nop; " \ + : \ + : "i" (MSR_DCE) \ + : "memory", "r12"); +#endif + } +} + +void _disable_dcache(void) +{ + if (cpuinfo.use_dcache) { +#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR + __asm__ __volatile__ (" \ + msrclr r0, %0; \ + nop; " \ + : \ + : "i" (MSR_DCE) \ + : "memory"); +#else + __asm__ __volatile__ (" \ + mfs r12, rmsr; \ + nop; \ + andi r12, r12, ~%0; \ + mts rmsr, r12; \ + nop; " \ + : \ + : "i" (MSR_DCE) \ + : "memory", "r12"); +#endif + } +} + +void _invalidate_dcache(unsigned int addr) +{ + if (cpuinfo.use_dcache) + __asm__ __volatile__ (" \ + wdc %0, r0" \ + : \ + : "r" (addr)); +} + +void __invalidate_icache_all(void) +{ + unsigned int i; + unsigned flags; + + if (cpuinfo.use_icache) { + local_irq_save(flags); + __disable_icache(); + + /* Just loop through cache size and invalidate, no need to add + CACHE_BASE address */ + for (i = 0; i < cpuinfo.icache_size; + i += cpuinfo.icache_line) + __invalidate_icache(i); + + __enable_icache(); + local_irq_restore(flags); + } +} + +void __invalidate_icache_range(unsigned long start, unsigned long end) +{ + unsigned int i; + unsigned flags; + unsigned int align; + + if (cpuinfo.use_icache) { + /* + * No need to cover entire cache range, + * just cover cache footprint + */ + end = min(start + cpuinfo.icache_size, end); + align = ~(cpuinfo.icache_line - 1); + start &= align; /* Make sure we are aligned */ + /* Push end up to the next cache line */ + end = ((end & align) + cpuinfo.icache_line); + + local_irq_save(flags); + __disable_icache(); + + for (i = start; i < end; i += cpuinfo.icache_line) + __invalidate_icache(i); + + __enable_icache(); + local_irq_restore(flags); + } +} + +void __invalidate_icache_page(struct vm_area_struct *vma, struct page *page) +{ + __invalidate_icache_all(); +} + +void __invalidate_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long adr, + int len) +{ + __invalidate_icache_all(); +} + +void __invalidate_cache_sigtramp(unsigned long addr) +{ + __invalidate_icache_range(addr, addr + 8); +} + +void __invalidate_dcache_all(void) +{ + unsigned int i; + unsigned flags; + + if (cpuinfo.use_dcache) { + local_irq_save(flags); + __disable_dcache(); + + /* + * Just loop through cache size and invalidate, + * no need to add CACHE_BASE address + */ + for (i = 0; i < cpuinfo.dcache_size; + i += cpuinfo.dcache_line) + __invalidate_dcache(i); + + __enable_dcache(); + local_irq_restore(flags); + } +} + +void __invalidate_dcache_range(unsigned long start, unsigned long end) +{ + unsigned int i; + unsigned flags; + unsigned int align; + + if (cpuinfo.use_dcache) { + /* + * No need to cover entire cache range, + * just cover cache footprint + */ + end = min(start + cpuinfo.dcache_size, end); + align = ~(cpuinfo.dcache_line - 1); + start &= align; /* Make sure we are aligned */ + /* Push end up to the next cache line */ + end = ((end & align) + cpuinfo.dcache_line); + local_irq_save(flags); + __disable_dcache(); + + for (i = start; i < end; i += cpuinfo.dcache_line) + __invalidate_dcache(i); + + __enable_dcache(); + local_irq_restore(flags); + } +} + +void __invalidate_dcache_page(struct vm_area_struct *vma, struct page *page) +{ + __invalidate_dcache_all(); +} + +void __invalidate_dcache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long adr, + int len) +{ + __invalidate_dcache_all(); +} diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c new file mode 100644 index 0000000..cf7424a --- /dev/null +++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c @@ -0,0 +1,101 @@ +/* + * Support for MicroBlaze PVR (processor version register) + * + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/string.h> +#include <asm/pvr.h> +#include <asm/cpuinfo.h> + +/* + * Helper macro to map between fields in our struct cpuinfo, and + * the PVR macros in pvr.h. + */ + +#define CI(c, p) { ci->c = PVR_##p(pvr); } +#define err_printk(x) \ + early_printk("ERROR: Microblaze " x " - different for PVR and DTS\n"); + +void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu) +{ + struct pvr_s pvr; + int temp; /* for saving temp value */ + get_pvr(&pvr); + + temp = PVR_USE_BARREL(pvr) | PVR_USE_MSR_INSTR(pvr) |\ + PVR_USE_PCMP_INSTR(pvr) | PVR_USE_DIV(pvr); + if (ci->use_instr != temp) + err_printk("BARREL, MSR, PCMP or DIV"); + ci->use_instr = temp; + + temp = PVR_USE_HW_MUL(pvr) | PVR_USE_MUL64(pvr); + if (ci->use_mult != temp) + err_printk("HW_MUL"); + ci->use_mult = temp; + + temp = PVR_USE_FPU(pvr) | PVR_USE_FPU2(pvr); + if (ci->use_fpu != temp) + err_printk("HW_FPU"); + ci->use_fpu = temp; + + ci->use_exc = PVR_OPCODE_0x0_ILLEGAL(pvr) |\ + PVR_UNALIGNED_EXCEPTION(pvr) |\ + PVR_ILL_OPCODE_EXCEPTION(pvr) |\ + PVR_IOPB_BUS_EXCEPTION(pvr) |\ + PVR_DOPB_BUS_EXCEPTION(pvr) |\ + PVR_DIV_ZERO_EXCEPTION(pvr) |\ + PVR_FPU_EXCEPTION(pvr) |\ + PVR_FSL_EXCEPTION(pvr); + + CI(pvr_user1, USER1); + CI(pvr_user2, USER2); + + CI(mmu, USE_MMU); + + CI(ver_code, VERSION); + + CI(use_icache, USE_ICACHE); + CI(icache_tagbits, ICACHE_ADDR_TAG_BITS); + CI(icache_write, ICACHE_ALLOW_WR); + CI(icache_line, ICACHE_LINE_LEN); + CI(icache_size, ICACHE_BYTE_SIZE); + CI(icache_base, ICACHE_BASEADDR); + CI(icache_high, ICACHE_HIGHADDR); + + CI(use_dcache, USE_DCACHE); + CI(dcache_tagbits, DCACHE_ADDR_TAG_BITS); + CI(dcache_write, DCACHE_ALLOW_WR); + CI(dcache_line, DCACHE_LINE_LEN); + CI(dcache_size, DCACHE_BYTE_SIZE); + CI(dcache_base, DCACHE_BASEADDR); + CI(dcache_high, DCACHE_HIGHADDR); + + CI(use_dopb, D_OPB); + CI(use_iopb, I_OPB); + CI(use_dlmb, D_LMB); + CI(use_ilmb, I_LMB); + CI(num_fsl, FSL_LINKS); + + CI(irq_edge, INTERRUPT_IS_EDGE); + CI(irq_positive, EDGE_IS_POSITIVE); + + CI(area_optimised, AREA_OPTIMISED); + + CI(hw_debug, DEBUG_ENABLED); + CI(num_pc_brk, NUMBER_OF_PC_BRK); + CI(num_rd_brk, NUMBER_OF_RD_ADDR_BRK); + CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK); + + CI(fpga_family_code, TARGET_FAMILY); + + /* take timebase-frequency from DTS */ + ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency"); +} diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c new file mode 100644 index 0000000..cfe44ef --- /dev/null +++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/string.h> +#include <asm/cpuinfo.h> +#include <asm/pvr.h> + +const static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY; +const static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER; + +#define err_printk(x) \ + early_printk("ERROR: Microblaze " x "- different for kernel and DTS\n"); + +void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) +{ + int i = 0; + + ci->use_instr = + (fcpu(cpu, "xlnx,use-barrel") ? PVR0_USE_BARREL_MASK : 0) | + (fcpu(cpu, "xlnx,use-msr-instr") ? PVR2_USE_MSR_INSTR : 0) | + (fcpu(cpu, "xlnx,use-pcmp-instr") ? PVR2_USE_PCMP_INSTR : 0) | + (fcpu(cpu, "xlnx,use-div") ? PVR0_USE_DIV_MASK : 0); + if (CONFIG_XILINX_MICROBLAZE0_USE_BARREL) + i |= PVR0_USE_BARREL_MASK; + if (CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR) + i |= PVR2_USE_MSR_INSTR; + if (CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) + i |= PVR2_USE_PCMP_INSTR; + if (CONFIG_XILINX_MICROBLAZE0_USE_DIV) + i |= PVR0_USE_DIV_MASK; + if (ci->use_instr != i) + err_printk("BARREL, MSR, PCMP or DIV"); + + ci->use_mult = fcpu(cpu, "xlnx,use-hw-mul"); + if (ci->use_mult != CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) + err_printk("HW_MUL"); + ci->use_mult = + (ci->use_mult > 1 ? + (PVR2_USE_MUL64_MASK | PVR0_USE_HW_MUL_MASK) : + (ci->use_mult == 1 ? PVR0_USE_HW_MUL_MASK : 0)); + + ci->use_fpu = fcpu(cpu, "xlnx,use-fpu"); + if (ci->use_fpu != CONFIG_XILINX_MICROBLAZE0_USE_FPU) + err_printk("HW_FPU"); + ci->use_fpu = (ci->use_fpu > 1 ? + (PVR2_USE_FPU2_MASK | PVR0_USE_FPU_MASK) : + (ci->use_fpu == 1 ? PVR0_USE_FPU_MASK : 0)); + + ci->use_exc = + (fcpu(cpu, "xlnx,unaligned-exceptions") ? + PVR2_UNALIGNED_EXC_MASK : 0) | + (fcpu(cpu, "xlnx,ill-opcode-exception") ? + PVR2_ILL_OPCODE_EXC_MASK : 0) | + (fcpu(cpu, "xlnx,iopb-bus-exception") ? + PVR2_IOPB_BUS_EXC_MASK : 0) | + (fcpu(cpu, "xlnx,dopb-bus-exception") ? + PVR2_DOPB_BUS_EXC_MASK : 0) | + (fcpu(cpu, "xlnx,div-zero-exception") ? + PVR2_DIV_ZERO_EXC_MASK : 0) | + (fcpu(cpu, "xlnx,fpu-exception") ? PVR2_FPU_EXC_MASK : 0) | + (fcpu(cpu, "xlnx,fsl-exception") ? PVR2_USE_EXTEND_FSL : 0); + + ci->use_icache = fcpu(cpu, "xlnx,use-icache"); + ci->icache_tagbits = fcpu(cpu, "xlnx,addr-tag-bits"); + ci->icache_write = fcpu(cpu, "xlnx,allow-icache-wr"); + ci->icache_line = fcpu(cpu, "xlnx,icache-line-len") << 2; + if (!ci->icache_line) { + if (fcpu(cpu, "xlnx,icache-use-fsl")) + ci->icache_line = 4 << 2; + else + ci->icache_line = 1 << 2; + } + ci->icache_size = fcpu(cpu, "i-cache-size"); + ci->icache_base = fcpu(cpu, "i-cache-baseaddr"); + ci->icache_high = fcpu(cpu, "i-cache-highaddr"); + + ci->use_dcache = fcpu(cpu, "xlnx,use-dcache"); + ci->dcache_tagbits = fcpu(cpu, "xlnx,dcache-addr-tag"); + ci->dcache_write = fcpu(cpu, "xlnx,allow-dcache-wr"); + ci->dcache_line = fcpu(cpu, "xlnx,dcache-line-len") << 2; + if (!ci->dcache_line) { + if (fcpu(cpu, "xlnx,dcache-use-fsl")) + ci->dcache_line = 4 << 2; + else + ci->dcache_line = 1 << 2; + } + ci->dcache_size = fcpu(cpu, "d-cache-size"); + ci->dcache_base = fcpu(cpu, "d-cache-baseaddr"); + ci->dcache_high = fcpu(cpu, "d-cache-highaddr"); + + ci->use_dopb = fcpu(cpu, "xlnx,d-opb"); + ci->use_iopb = fcpu(cpu, "xlnx,i-opb"); + ci->use_dlmb = fcpu(cpu, "xlnx,d-lmb"); + ci->use_ilmb = fcpu(cpu, "xlnx,i-lmb"); + + ci->num_fsl = fcpu(cpu, "xlnx,fsl-links"); + ci->irq_edge = fcpu(cpu, "xlnx,interrupt-is-edge"); + ci->irq_positive = fcpu(cpu, "xlnx,edge-is-positive"); + ci->area_optimised = 0; + + ci->hw_debug = fcpu(cpu, "xlnx,debug-enabled"); + ci->num_pc_brk = fcpu(cpu, "xlnx,number-of-pc-brk"); + ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk"); + ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk"); + + ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency"); + + ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1"); + ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); + + ci->mmu = fcpu(cpu, "xlnx,use-mmu"); + + ci->ver_code = 0; + ci->fpga_family_code = 0; + + /* Do various fixups based on CPU version and FPGA family strings */ + + /* Resolved the CPU version code */ + for (i = 0; cpu_ver_lookup[i].s != NULL; i++) { + if (strcmp(cpu_ver_lookup[i].s, cpu_ver_string) == 0) + ci->ver_code = cpu_ver_lookup[i].k; + } + + /* Resolved the fpga family code */ + for (i = 0; family_string_lookup[i].s != NULL; i++) { + if (strcmp(family_string_lookup[i].s, family_string) == 0) + ci->fpga_family_code = family_string_lookup[i].k; + } + + /* FIXME - mb3 and spartan2 do not exist in PVR */ + /* This is mb3 and on a non Spartan2 */ + if (ci->ver_code == 0x20 && ci->fpga_family_code != 0xf0) + /* Hardware Multiplier in use */ + ci->use_mult = 1; +} diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c new file mode 100644 index 0000000..4a740df --- /dev/null +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/slab.h> +#include <asm/cpuinfo.h> +#include <asm/pvr.h> + +const struct cpu_ver_key cpu_ver_lookup[] = { + /* These key value are as per MBV field in PVR0 */ + {"5.00.a", 0x01}, + {"5.00.b", 0x02}, + {"5.00.c", 0x03}, + {"6.00.a", 0x04}, + {"6.00.b", 0x06}, + {"7.00.a", 0x05}, + {"7.00.b", 0x07}, + {"7.10.a", 0x08}, + {"7.10.b", 0x09}, + {"7.10.c", 0x0a}, + {"7.10.d", 0x0b}, + /* FIXME There is no keycode defined in MBV for these versions */ + {"2.10.a", 0x10}, + {"3.00.a", 0x20}, + {"4.00.a", 0x30}, + {"4.00.b", 0x40}, + {NULL, 0}, +}; + +/* + * FIXME Not sure if the actual key is defined by Xilinx in the PVR + */ +const struct family_string_key family_string_lookup[] = { + {"virtex2", 0x4}, + {"virtex2pro", 0x5}, + {"spartan3", 0x6}, + {"virtex4", 0x7}, + {"virtex5", 0x8}, + {"spartan3e", 0x9}, + {"spartan3a", 0xa}, + {"spartan3an", 0xb}, + {"spartan3adsp", 0xc}, + /* FIXME There is no key code defined for spartan2 */ + {"spartan2", 0xf0}, + {NULL, 0}, +}; + +struct cpuinfo cpuinfo; + +void __init setup_cpuinfo(void) +{ + struct device_node *cpu = NULL; + + cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu"); + if (!cpu) + printk(KERN_ERR "You don't have cpu!!!\n"); + + printk(KERN_INFO "%s: initialising\n", __func__); + + switch (cpu_has_pvr()) { + case 0: + printk(KERN_WARNING + "%s: No PVR support. Using static CPU info from FDT\n", + __func__); + set_cpuinfo_static(&cpuinfo, cpu); + break; +/* FIXME I found weird behavior with MB 7.00.a/b + * please do not use FULL PVR with MMU */ + case 1: + printk(KERN_INFO "%s: Using full CPU PVR support\n", + __func__); + set_cpuinfo_static(&cpuinfo, cpu); + set_cpuinfo_pvr_full(&cpuinfo, cpu); + break; + default: + printk(KERN_WARNING "%s: Unsupported PVR setting\n", __func__); + set_cpuinfo_static(&cpuinfo, cpu); + } +} diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c new file mode 100644 index 0000000..3b6212b --- /dev/null +++ b/arch/microblaze/kernel/cpu/mb.c @@ -0,0 +1,148 @@ +/* + * CPU-version specific code + * + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2006-2009 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/string.h> +#include <linux/seq_file.h> +#include <linux/cpu.h> +#include <linux/initrd.h> + +#include <linux/bug.h> +#include <asm/cpuinfo.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <asm/page.h> +#include <linux/param.h> +#include <asm/pvr.h> +#include <asm/sections.h> +#include <asm/setup.h> + +static int show_cpuinfo(struct seq_file *m, void *v) +{ + int count = 0; + char *fpga_family = "Unknown"; + char *cpu_ver = "Unknown"; + int i; + + /* Denormalised to get the fpga family string */ + for (i = 0; family_string_lookup[i].s != NULL; i++) { + if (cpuinfo.fpga_family_code == family_string_lookup[i].k) { + fpga_family = (char *)family_string_lookup[i].s; + break; + } + } + + /* Denormalised to get the hw version string */ + for (i = 0; cpu_ver_lookup[i].s != NULL; i++) { + if (cpuinfo.ver_code == cpu_ver_lookup[i].k) { + cpu_ver = (char *)cpu_ver_lookup[i].s; + break; + } + } + + count = seq_printf(m, + "CPU-Family: MicroBlaze\n" + "FPGA-Arch: %s\n" + "CPU-Ver: %s\n" + "CPU-MHz: %d.%02d\n" + "BogoMips: %lu.%02lu\n", + fpga_family, + cpu_ver, + cpuinfo.cpu_clock_freq / + 1000000, + cpuinfo.cpu_clock_freq % + 1000000, + loops_per_jiffy / (500000 / HZ), + (loops_per_jiffy / (5000 / HZ)) % 100); + + count += seq_printf(m, + "HW:\n Shift:\t\t%s\n" + " MSR:\t\t%s\n" + " PCMP:\t\t%s\n" + " DIV:\t\t%s\n", + (cpuinfo.use_instr & PVR0_USE_BARREL_MASK) ? "yes" : "no", + (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) ? "yes" : "no", + (cpuinfo.use_instr & PVR2_USE_PCMP_INSTR) ? "yes" : "no", + (cpuinfo.use_instr & PVR0_USE_DIV_MASK) ? "yes" : "no"); + + count += seq_printf(m, + " MMU:\t\t%x\n", + cpuinfo.mmu); + + count += seq_printf(m, + " MUL:\t\t%s\n" + " FPU:\t\t%s\n", + (cpuinfo.use_mult & PVR2_USE_MUL64_MASK) ? "v2" : + (cpuinfo.use_mult & PVR0_USE_HW_MUL_MASK) ? "v1" : "no", + (cpuinfo.use_fpu & PVR2_USE_FPU2_MASK) ? "v2" : + (cpuinfo.use_fpu & PVR0_USE_FPU_MASK) ? "v1" : "no"); + + count += seq_printf(m, + " Exc:\t\t%s%s%s%s%s%s%s%s\n", + (cpuinfo.use_exc & PVR2_OPCODE_0x0_ILL_MASK) ? "op0x0 " : "", + (cpuinfo.use_exc & PVR2_UNALIGNED_EXC_MASK) ? "unal " : "", + (cpuinfo.use_exc & PVR2_ILL_OPCODE_EXC_MASK) ? "ill " : "", + (cpuinfo.use_exc & PVR2_IOPB_BUS_EXC_MASK) ? "iopb " : "", + (cpuinfo.use_exc & PVR2_DOPB_BUS_EXC_MASK) ? "dopb " : "", + (cpuinfo.use_exc & PVR2_DIV_ZERO_EXC_MASK) ? "zero " : "", + (cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "", + (cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : ""); + + if (cpuinfo.use_icache) + count += seq_printf(m, + "Icache:\t\t%ukB\n", + cpuinfo.icache_size >> 10); + else + count += seq_printf(m, "Icache:\t\tno\n"); + + if (cpuinfo.use_dcache) + count += seq_printf(m, + "Dcache:\t\t%ukB\n", + cpuinfo.dcache_size >> 10); + else + count += seq_printf(m, "Dcache:\t\tno\n"); + + count += seq_printf(m, + "HW-Debug:\t%s\n", + cpuinfo.hw_debug ? "yes" : "no"); + + count += seq_printf(m, + "PVR-USR1:\t%x\n" + "PVR-USR2:\t%x\n", + cpuinfo.pvr_user1, + cpuinfo.pvr_user2); + + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + int i = *pos; + + return i < NR_CPUS ? (void *) (i + 1) : NULL; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +const struct seq_operations cpuinfo_op = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, +}; diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c new file mode 100644 index 0000000..c9a4340 --- /dev/null +++ b/arch/microblaze/kernel/cpu/pvr.c @@ -0,0 +1,81 @@ +/* + * Support for MicroBlaze PVR (processor version register) + * + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/kernel.h> +#include <linux/compiler.h> +#include <asm/system.h> +#include <asm/exceptions.h> +#include <asm/pvr.h> + +/* + * Until we get an assembler that knows about the pvr registers, + * this horrible cruft will have to do. + * That hardcoded opcode is mfs r3, rpvrNN + */ + +#define get_single_pvr(pvrid, val) \ +{ \ + register unsigned tmp __asm__("r3"); \ + tmp = 0x0; /* Prevent warning about unused */ \ + __asm__ __volatile__ ( \ + ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \ + : "=r" (tmp) : : "memory"); \ + val = tmp; \ +} + +/* + * Does the CPU support the PVR register? + * return value: + * 0: no PVR + * 1: simple PVR + * 2: full PVR + * + * This must work on all CPU versions, including those before the + * PVR was even an option. + */ + +int cpu_has_pvr(void) +{ + unsigned flags; + unsigned pvr0; + + local_save_flags(flags); + + /* PVR bit in MSR tells us if there is any support */ + if (!(flags & PVR_MSR_BIT)) + return 0; + + get_single_pvr(0x00, pvr0); + pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0); + + if (pvr0 & PVR0_PVR_FULL_MASK) + return 1; + + /* for partial PVR use static cpuinfo */ + return 2; +} + +void get_pvr(struct pvr_s *p) +{ + get_single_pvr(0, p->pvr[0]); + get_single_pvr(1, p->pvr[1]); + get_single_pvr(2, p->pvr[2]); + get_single_pvr(3, p->pvr[3]); + get_single_pvr(4, p->pvr[4]); + get_single_pvr(5, p->pvr[5]); + get_single_pvr(6, p->pvr[6]); + get_single_pvr(7, p->pvr[7]); + get_single_pvr(8, p->pvr[8]); + get_single_pvr(9, p->pvr[9]); + get_single_pvr(10, p->pvr[10]); + get_single_pvr(11, p->pvr[11]); +} diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c new file mode 100644 index 0000000..62cc789 --- /dev/null +++ b/arch/microblaze/kernel/early_printk.c @@ -0,0 +1,107 @@ +/* + * Early printk support for Microblaze. + * + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2003-2006 Yasushi SHOJI <yashi@atmark-techno.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/console.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/string.h> +#include <linux/tty.h> +#include <linux/io.h> +#include <asm/processor.h> +#include <linux/fcntl.h> +#include <asm/setup.h> +#include <asm/prom.h> + +static u32 early_console_initialized; +static u32 base_addr; + +static void early_printk_putc(char c) +{ + /* + * Limit how many times we'll spin waiting for TX FIFO status. + * This will prevent lockups if the base address is incorrectly + * set, or any other issue on the UARTLITE. + * This limit is pretty arbitrary, unless we are at about 10 baud + * we'll never timeout on a working UART. + */ + + unsigned retries = 10000; + /* read status bit - 0x8 offset */ + while (retries-- && (in_be32(base_addr + 8) & (1 << 3))) + ; + + /* Only attempt the iowrite if we didn't timeout */ + /* write to TX_FIFO - 0x4 offset */ + if (retries) + out_be32(base_addr + 4, c & 0xff); +} + +static void early_printk_write(struct console *unused, + const char *s, unsigned n) +{ + while (*s && n-- > 0) { + early_printk_putc(*s); + if (*s == '\n') + early_printk_putc('\r'); + s++; + } +} + +static struct console early_serial_console = { + .name = "earlyser", + .write = early_printk_write, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +static struct console *early_console = &early_serial_console; + +void early_printk(const char *fmt, ...) +{ + char buf[512]; + int n; + va_list ap; + + if (early_console_initialized) { + va_start(ap, fmt); + n = vscnprintf(buf, 512, fmt, ap); + early_console->write(early_console, buf, n); + va_end(ap); + } +} + +int __init setup_early_printk(char *opt) +{ + if (early_console_initialized) + return 1; + + base_addr = early_uartlite_console(); + if (base_addr) { + early_console_initialized = 1; + early_printk("early_printk_console is enabled at 0x%08x\n", + base_addr); + + /* register_console(early_console); */ + + return 0; + } else + return 1; +} + +void __init disable_early_printk(void) +{ + if (!early_console_initialized || !early_console) + return; + printk(KERN_WARNING "disabling early console\n"); + unregister_console(early_console); + early_console_initialized = 0; +} diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S new file mode 100644 index 0000000..f24b126 --- /dev/null +++ b/arch/microblaze/kernel/entry-nommu.S @@ -0,0 +1,596 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/linkage.h> +#include <asm/thread_info.h> +#include <asm/errno.h> +#include <asm/entry.h> +#include <asm/asm-offsets.h> +#include <asm/registers.h> +#include <asm/unistd.h> +#include <asm/percpu.h> +#include <asm/signal.h> + +#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR + .macro disable_irq + msrclr r0, MSR_IE + .endm + + .macro enable_irq + msrset r0, MSR_IE + .endm + + .macro clear_bip + msrclr r0, MSR_BIP + .endm +#else + .macro disable_irq + mfs r11, rmsr + andi r11, r11, ~MSR_IE + mts rmsr, r11 + .endm + + .macro enable_irq + mfs r11, rmsr + ori r11, r11, MSR_IE + mts rmsr, r11 + .endm + + .macro clear_bip + mfs r11, rmsr + andi r11, r11, ~MSR_BIP + mts rmsr, r11 + .endm +#endif + +ENTRY(_interrupt) + swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ + swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ + lwi r11, r0, PER_CPU(KM) /* load mode indicator */ + beqid r11, 1f + nop + brid 2f /* jump over */ + addik r1, r1, (-PT_SIZE) /* room for pt_regs (delay slot) */ +1: /* switch to kernel stack */ + lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ + lwi r1, r1, TS_THREAD_INFO /* get the thread info */ + /* calculate kernel stack pointer */ + addik r1, r1, THREAD_SIZE - PT_SIZE +2: + swi r11, r1, PT_MODE /* store the mode */ + lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ + swi r2, r1, PT_R2 + swi r3, r1, PT_R3 + swi r4, r1, PT_R4 + swi r5, r1, PT_R5 + swi r6, r1, PT_R6 + swi r7, r1, PT_R7 + swi r8, r1, PT_R8 + swi r9, r1, PT_R9 + swi r10, r1, PT_R10 + swi r11, r1, PT_R11 + swi r12, r1, PT_R12 + swi r13, r1, PT_R13 + swi r14, r1, PT_R14 + swi r14, r1, PT_PC + swi r15, r1, PT_R15 + swi r16, r1, PT_R16 + swi r17, r1, PT_R17 + swi r18, r1, PT_R18 + swi r19, r1, PT_R19 + swi r20, r1, PT_R20 + swi r21, r1, PT_R21 + swi r22, r1, PT_R22 + swi r23, r1, PT_R23 + swi r24, r1, PT_R24 + swi r25, r1, PT_R25 + swi r26, r1, PT_R26 + swi r27, r1, PT_R27 + swi r28, r1, PT_R28 + swi r29, r1, PT_R29 + swi r30, r1, PT_R30 + swi r31, r1, PT_R31 + /* special purpose registers */ + mfs r11, rmsr + swi r11, r1, PT_MSR + mfs r11, rear + swi r11, r1, PT_EAR + mfs r11, resr + swi r11, r1, PT_ESR + mfs r11, rfsr + swi r11, r1, PT_FSR + /* reload original stack pointer and save it */ + lwi r11, r0, PER_CPU(ENTRY_SP) + swi r11, r1, PT_R1 + /* update mode indicator we are in kernel mode */ + addik r11, r0, 1 + swi r11, r0, PER_CPU(KM) + /* restore r31 */ + lwi r31, r0, PER_CPU(CURRENT_SAVE) + /* prepare the link register, the argument and jump */ + la r15, r0, ret_from_intr - 8 + addk r6, r0, r15 + braid do_IRQ + add r5, r0, r1 + +ret_from_intr: + lwi r11, r1, PT_MODE + bneid r11, 3f + + lwi r6, r31, TS_THREAD_INFO /* get thread info */ + lwi r19, r6, TI_FLAGS /* get flags in thread info */ + /* do an extra work if any bits are set */ + + andi r11, r19, _TIF_NEED_RESCHED + beqi r11, 1f + bralid r15, schedule + nop +1: andi r11, r19, _TIF_SIGPENDING + beqid r11, no_intr_reshed + addk r5, r1, r0 + addk r7, r0, r0 + bralid r15, do_signal + addk r6, r0, r0 + +no_intr_reshed: + /* save mode indicator */ + lwi r11, r1, PT_MODE +3: + swi r11, r0, PER_CPU(KM) + + /* save r31 */ + swi r31, r0, PER_CPU(CURRENT_SAVE) +restore_context: + /* special purpose registers */ + lwi r11, r1, PT_FSR + mts rfsr, r11 + lwi r11, r1, PT_ESR + mts resr, r11 + lwi r11, r1, PT_EAR + mts rear, r11 + lwi r11, r1, PT_MSR + mts rmsr, r11 + + lwi r31, r1, PT_R31 + lwi r30, r1, PT_R30 + lwi r29, r1, PT_R29 + lwi r28, r1, PT_R28 + lwi r27, r1, PT_R27 + lwi r26, r1, PT_R26 + lwi r25, r1, PT_R25 + lwi r24, r1, PT_R24 + lwi r23, r1, PT_R23 + lwi r22, r1, PT_R22 + lwi r21, r1, PT_R21 + lwi r20, r1, PT_R20 + lwi r19, r1, PT_R19 + lwi r18, r1, PT_R18 + lwi r17, r1, PT_R17 + lwi r16, r1, PT_R16 + lwi r15, r1, PT_R15 + lwi r14, r1, PT_PC + lwi r13, r1, PT_R13 + lwi r12, r1, PT_R12 + lwi r11, r1, PT_R11 + lwi r10, r1, PT_R10 + lwi r9, r1, PT_R9 + lwi r8, r1, PT_R8 + lwi r7, r1, PT_R7 + lwi r6, r1, PT_R6 + lwi r5, r1, PT_R5 + lwi r4, r1, PT_R4 + lwi r3, r1, PT_R3 + lwi r2, r1, PT_R2 + lwi r1, r1, PT_R1 + rtid r14, 0 + nop + +ENTRY(_reset) + brai 0; + +ENTRY(_user_exception) + swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ + swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ + lwi r11, r0, PER_CPU(KM) /* load mode indicator */ + beqid r11, 1f /* Already in kernel mode? */ + nop + brid 2f /* jump over */ + addik r1, r1, (-PT_SIZE) /* Room for pt_regs (delay slot) */ +1: /* Switch to kernel stack */ + lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ + lwi r1, r1, TS_THREAD_INFO /* get the thread info */ + /* calculate kernel stack pointer */ + addik r1, r1, THREAD_SIZE - PT_SIZE + swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ + lwi r11, r0, PER_CPU(KM) /* load mode indicator */ +2: + swi r11, r1, PT_MODE /* store the mode */ + lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ + /* save them on stack */ + swi r2, r1, PT_R2 + swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */ + swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */ + swi r5, r1, PT_R5 + swi r6, r1, PT_R6 + swi r7, r1, PT_R7 + swi r8, r1, PT_R8 + swi r9, r1, PT_R9 + swi r10, r1, PT_R10 + swi r11, r1, PT_R11 + /* r12: _always_ in clobber list; see unistd.h */ + swi r12, r1, PT_R12 + swi r13, r1, PT_R13 + /* r14: _always_ in clobber list; see unistd.h */ + swi r14, r1, PT_R14 + /* but we want to return to the next inst. */ + addik r14, r14, 0x4 + swi r14, r1, PT_PC /* increment by 4 and store in pc */ + swi r15, r1, PT_R15 + swi r16, r1, PT_R16 + swi r17, r1, PT_R17 + swi r18, r1, PT_R18 + swi r19, r1, PT_R19 + swi r20, r1, PT_R20 + swi r21, r1, PT_R21 + swi r22, r1, PT_R22 + swi r23, r1, PT_R23 + swi r24, r1, PT_R24 + swi r25, r1, PT_R25 + swi r26, r1, PT_R26 + swi r27, r1, PT_R27 + swi r28, r1, PT_R28 + swi r29, r1, PT_R29 + swi r30, r1, PT_R30 + swi r31, r1, PT_R31 + + disable_irq + nop /* make sure IE bit is in effect */ + clear_bip /* once IE is in effect it is safe to clear BIP */ + nop + + /* special purpose registers */ + mfs r11, rmsr + swi r11, r1, PT_MSR + mfs r11, rear + swi r11, r1, PT_EAR + mfs r11, resr + swi r11, r1, PT_ESR + mfs r11, rfsr + swi r11, r1, PT_FSR + /* reload original stack pointer and save it */ + lwi r11, r0, PER_CPU(ENTRY_SP) + swi r11, r1, PT_R1 + /* update mode indicator we are in kernel mode */ + addik r11, r0, 1 + swi r11, r0, PER_CPU(KM) + /* restore r31 */ + lwi r31, r0, PER_CPU(CURRENT_SAVE) + /* re-enable interrupts now we are in kernel mode */ + enable_irq + + /* See if the system call number is valid. */ + addi r11, r12, -__NR_syscalls + bgei r11, 1f /* return to user if not valid */ + /* Figure out which function to use for this system call. */ + /* Note Microblaze barrel shift is optional, so don't rely on it */ + add r12, r12, r12 /* convert num -> ptr */ + add r12, r12, r12 + lwi r12, r12, sys_call_table /* Get function pointer */ + la r15, r0, ret_to_user-8 /* set return address */ + bra r12 /* Make the system call. */ + bri 0 /* won't reach here */ +1: + brid ret_to_user /* jump to syscall epilogue */ + addi r3, r0, -ENOSYS /* set errno in delay slot */ + +/* + * Debug traps are like a system call, but entered via brki r14, 0x60 + * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal + * will handle the rest + */ +ENTRY(_debug_exception) + swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ + lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ + lwi r1, r1, TS_THREAD_INFO /* get the thread info */ + addik r1, r1, THREAD_SIZE - PT_SIZE /* get the kernel stack */ + swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ + lwi r11, r0, PER_CPU(KM) /* load mode indicator */ +//save_context: + swi r11, r1, PT_MODE /* store the mode */ + lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ + /* save them on stack */ + swi r2, r1, PT_R2 + swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */ + swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */ + swi r5, r1, PT_R5 + swi r6, r1, PT_R6 + swi r7, r1, PT_R7 + swi r8, r1, PT_R8 + swi r9, r1, PT_R9 + swi r10, r1, PT_R10 + swi r11, r1, PT_R11 + /* r12: _always_ in clobber list; see unistd.h */ + swi r12, r1, PT_R12 + swi r13, r1, PT_R13 + /* r14: _always_ in clobber list; see unistd.h */ + swi r14, r1, PT_R14 + swi r14, r1, PT_PC /* Will return to interrupted instruction */ + swi r15, r1, PT_R15 + swi r16, r1, PT_R16 + swi r17, r1, PT_R17 + swi r18, r1, PT_R18 + swi r19, r1, PT_R19 + swi r20, r1, PT_R20 + swi r21, r1, PT_R21 + swi r22, r1, PT_R22 + swi r23, r1, PT_R23 + swi r24, r1, PT_R24 + swi r25, r1, PT_R25 + swi r26, r1, PT_R26 + swi r27, r1, PT_R27 + swi r28, r1, PT_R28 + swi r29, r1, PT_R29 + swi r30, r1, PT_R30 + swi r31, r1, PT_R31 + + disable_irq + nop /* make sure IE bit is in effect */ + clear_bip /* once IE is in effect it is safe to clear BIP */ + nop + + /* special purpose registers */ + mfs r11, rmsr + swi r11, r1, PT_MSR + mfs r11, rear + swi r11, r1, PT_EAR + mfs r11, resr + swi r11, r1, PT_ESR + mfs r11, rfsr + swi r11, r1, PT_FSR + /* reload original stack pointer and save it */ + lwi r11, r0, PER_CPU(ENTRY_SP) + swi r11, r1, PT_R1 + /* update mode indicator we are in kernel mode */ + addik r11, r0, 1 + swi r11, r0, PER_CPU(KM) + /* restore r31 */ + lwi r31, r0, PER_CPU(CURRENT_SAVE) + /* re-enable interrupts now we are in kernel mode */ + enable_irq + + addi r5, r0, SIGTRAP /* sending the trap signal */ + add r6, r0, r31 /* to current */ + bralid r15, send_sig + add r7, r0, r0 /* 3rd param zero */ + + /* Restore r3/r4 to work around how ret_to_user works */ + lwi r3, r1, PT_R3 + lwi r4, r1, PT_R4 + bri ret_to_user + +ENTRY(_break) + bri 0 + +/* struct task_struct *_switch_to(struct thread_info *prev, + struct thread_info *next); */ +ENTRY(_switch_to) + /* prepare return value */ + addk r3, r0, r31 + + /* save registers in cpu_context */ + /* use r11 and r12, volatile registers, as temp register */ + addik r11, r5, TI_CPU_CONTEXT + swi r1, r11, CC_R1 + swi r2, r11, CC_R2 + /* skip volatile registers. + * they are saved on stack when we jumped to _switch_to() */ + /* dedicated registers */ + swi r13, r11, CC_R13 + swi r14, r11, CC_R14 + swi r15, r11, CC_R15 + swi r16, r11, CC_R16 + swi r17, r11, CC_R17 + swi r18, r11, CC_R18 + /* save non-volatile registers */ + swi r19, r11, CC_R19 + swi r20, r11, CC_R20 + swi r21, r11, CC_R21 + swi r22, r11, CC_R22 + swi r23, r11, CC_R23 + swi r24, r11, CC_R24 + swi r25, r11, CC_R25 + swi r26, r11, CC_R26 + swi r27, r11, CC_R27 + swi r28, r11, CC_R28 + swi r29, r11, CC_R29 + swi r30, r11, CC_R30 + /* special purpose registers */ + mfs r12, rmsr + swi r12, r11, CC_MSR + mfs r12, rear + swi r12, r11, CC_EAR + mfs r12, resr + swi r12, r11, CC_ESR + mfs r12, rfsr + swi r12, r11, CC_FSR + + /* update r31, the current */ + lwi r31, r6, TI_TASK + swi r31, r0, PER_CPU(CURRENT_SAVE) + + /* get new process' cpu context and restore */ + addik r11, r6, TI_CPU_CONTEXT + + /* special purpose registers */ + lwi r12, r11, CC_FSR + mts rfsr, r12 + lwi r12, r11, CC_ESR + mts resr, r12 + lwi r12, r11, CC_EAR + mts rear, r12 + lwi r12, r11, CC_MSR + mts rmsr, r12 + /* non-volatile registers */ + lwi r30, r11, CC_R30 + lwi r29, r11, CC_R29 + lwi r28, r11, CC_R28 + lwi r27, r11, CC_R27 + lwi r26, r11, CC_R26 + lwi r25, r11, CC_R25 + lwi r24, r11, CC_R24 + lwi r23, r11, CC_R23 + lwi r22, r11, CC_R22 + lwi r21, r11, CC_R21 + lwi r20, r11, CC_R20 + lwi r19, r11, CC_R19 + /* dedicated registers */ + lwi r18, r11, CC_R18 + lwi r17, r11, CC_R17 + lwi r16, r11, CC_R16 + lwi r15, r11, CC_R15 + lwi r14, r11, CC_R14 + lwi r13, r11, CC_R13 + /* skip volatile registers */ + lwi r2, r11, CC_R2 + lwi r1, r11, CC_R1 + + rtsd r15, 8 + nop + +ENTRY(ret_from_fork) + addk r5, r0, r3 + addk r6, r0, r1 + brlid r15, schedule_tail + nop + swi r31, r1, PT_R31 /* save r31 in user context. */ + /* will soon be restored to r31 in ret_to_user */ + addk r3, r0, r0 + brid ret_to_user + nop + +work_pending: + andi r11, r19, _TIF_NEED_RESCHED + beqi r11, 1f + bralid r15, schedule + nop +1: andi r11, r19, _TIF_SIGPENDING + beqi r11, no_work_pending + addk r5, r1, r0 + addik r7, r0, 1 + bralid r15, do_signal + addk r6, r0, r0 + bri no_work_pending + +ENTRY(ret_to_user) + disable_irq + + swi r4, r1, PT_R4 /* return val */ + swi r3, r1, PT_R3 /* return val */ + + lwi r6, r31, TS_THREAD_INFO /* get thread info */ + lwi r19, r6, TI_FLAGS /* get flags in thread info */ + bnei r19, work_pending /* do an extra work if any bits are set */ +no_work_pending: + disable_irq + + /* save r31 */ + swi r31, r0, PER_CPU(CURRENT_SAVE) + /* save mode indicator */ + lwi r18, r1, PT_MODE + swi r18, r0, PER_CPU(KM) +//restore_context: + /* special purpose registers */ + lwi r18, r1, PT_FSR + mts rfsr, r18 + lwi r18, r1, PT_ESR + mts resr, r18 + lwi r18, r1, PT_EAR + mts rear, r18 + lwi r18, r1, PT_MSR + mts rmsr, r18 + + lwi r31, r1, PT_R31 + lwi r30, r1, PT_R30 + lwi r29, r1, PT_R29 + lwi r28, r1, PT_R28 + lwi r27, r1, PT_R27 + lwi r26, r1, PT_R26 + lwi r25, r1, PT_R25 + lwi r24, r1, PT_R24 + lwi r23, r1, PT_R23 + lwi r22, r1, PT_R22 + lwi r21, r1, PT_R21 + lwi r20, r1, PT_R20 + lwi r19, r1, PT_R19 + lwi r18, r1, PT_R18 + lwi r17, r1, PT_R17 + lwi r16, r1, PT_R16 + lwi r15, r1, PT_R15 + lwi r14, r1, PT_PC + lwi r13, r1, PT_R13 + lwi r12, r1, PT_R12 + lwi r11, r1, PT_R11 + lwi r10, r1, PT_R10 + lwi r9, r1, PT_R9 + lwi r8, r1, PT_R8 + lwi r7, r1, PT_R7 + lwi r6, r1, PT_R6 + lwi r5, r1, PT_R5 + lwi r4, r1, PT_R4 /* return val */ + lwi r3, r1, PT_R3 /* return val */ + lwi r2, r1, PT_R2 + lwi r1, r1, PT_R1 + + rtid r14, 0 + nop + +sys_vfork_wrapper: + brid sys_vfork + addk r5, r1, r0 + +sys_clone_wrapper: + brid sys_clone + addk r7, r1, r0 + +sys_execve_wrapper: + brid sys_execve + addk r8, r1, r0 + +sys_sigreturn_wrapper: + brid sys_sigreturn + addk r5, r1, r0 + +sys_rt_sigreturn_wrapper: + brid sys_rt_sigreturn + addk r5, r1, r0 + +sys_sigsuspend_wrapper: + brid sys_rt_sigsuspend + addk r6, r1, r0 + +sys_rt_sigsuspend_wrapper: + brid sys_rt_sigsuspend + addk r7, r1, r0 + + /* Interrupt vector table */ + .section .init.ivt, "ax" + .org 0x0 + brai _reset + brai _user_exception + brai _interrupt + brai _break + brai _hw_exception_handler + .org 0x60 + brai _debug_exception + +.section .rodata,"a" +#include "syscall_table.S" + +syscall_table_size=(.-sys_call_table) diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c new file mode 100644 index 0000000..4a8a406 --- /dev/null +++ b/arch/microblaze/kernel/exceptions.c @@ -0,0 +1,124 @@ +/* + * HW exception handling + * + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +/* + * This file handles the architecture-dependent parts of hardware exceptions + */ + +#include <linux/kernel.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/kallsyms.h> +#include <linux/module.h> + +#include <asm/exceptions.h> +#include <asm/entry.h> /* For KM CPU var */ +#include <asm/uaccess.h> +#include <asm/errno.h> +#include <asm/ptrace.h> +#include <asm/current.h> + +#define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02 +#define MICROBLAZE_IBUS_EXCEPTION 0x03 +#define MICROBLAZE_DBUS_EXCEPTION 0x04 +#define MICROBLAZE_DIV_ZERO_EXCEPTION 0x05 +#define MICROBLAZE_FPU_EXCEPTION 0x06 +#define MICROBLAZE_PRIVILEG_EXCEPTION 0x07 + +static DEFINE_SPINLOCK(die_lock); + +void die(const char *str, struct pt_regs *fp, long err) +{ + console_verbose(); + spin_lock_irq(&die_lock); + printk(KERN_WARNING "Oops: %s, sig: %ld\n", str, err); + show_regs(fp); + spin_unlock_irq(&die_lock); + /* do_exit() should take care of panic'ing from an interrupt + * context so we don't handle it here + */ + do_exit(err); +} + +void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) +{ + siginfo_t info; + + if (kernel_mode(regs)) { + debugger(regs); + die("Exception in kernel mode", regs, signr); + } + info.si_signo = signr; + info.si_errno = 0; + info.si_code = code; + info.si_addr = (void __user *) addr; + force_sig_info(signr, &info, current); +} + +asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, + int fsr, int addr) +{ +#if 0 + printk(KERN_WARNING "Exception %02x in %s mode, FSR=%08x PC=%08x ESR=%08x\n", + type, user_mode(regs) ? "user" : "kernel", fsr, + (unsigned int) regs->pc, (unsigned int) regs->esr); +#endif + + switch (type & 0x1F) { + case MICROBLAZE_ILL_OPCODE_EXCEPTION: + _exception(SIGILL, regs, ILL_ILLOPC, addr); + break; + case MICROBLAZE_IBUS_EXCEPTION: + if (user_mode(regs)) { + printk(KERN_WARNING "Instruction bus error exception in user mode.\n"); + _exception(SIGBUS, regs, BUS_ADRERR, addr); + return; + } + printk(KERN_WARNING "Instruction bus error exception in kernel mode.\n"); + die("bus exception", regs, SIGBUS); + break; + case MICROBLAZE_DBUS_EXCEPTION: + if (user_mode(regs)) { + printk(KERN_WARNING "Data bus error exception in user mode.\n"); + _exception(SIGBUS, regs, BUS_ADRERR, addr); + return; + } + printk(KERN_WARNING "Data bus error exception in kernel mode.\n"); + die("bus exception", regs, SIGBUS); + break; + case MICROBLAZE_DIV_ZERO_EXCEPTION: + printk(KERN_WARNING "Divide by zero exception\n"); + _exception(SIGILL, regs, ILL_ILLOPC, addr); + break; + + case MICROBLAZE_FPU_EXCEPTION: + /* IEEE FP exception */ + /* I removed fsr variable and use code var for storing fsr */ + if (fsr & FSR_IO) + fsr = FPE_FLTINV; + else if (fsr & FSR_OF) + fsr = FPE_FLTOVF; + else if (fsr & FSR_UF) + fsr = FPE_FLTUND; + else if (fsr & FSR_DZ) + fsr = FPE_FLTDIV; + else if (fsr & FSR_DO) + fsr = FPE_FLTRES; + _exception(SIGFPE, regs, fsr, addr); + break; + + default: + printk(KERN_WARNING "Unexpected exception %02x " + "PC=%08x in %s mode\n", type, (unsigned int) addr, + kernel_mode(regs) ? "kernel" : "user"); + } + return; +} diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S new file mode 100644 index 0000000..319dc35 --- /dev/null +++ b/arch/microblaze/kernel/head.S @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/linkage.h> +#include <asm/thread_info.h> +#include <asm/page.h> + + .text +ENTRY(_start) + mfs r1, rmsr + andi r1, r1, ~2 + mts rmsr, r1 + +/* save fdt to kernel location */ +/* r7 stores pointer to fdt blob */ + beqi r7, no_fdt_arg + or r11, r0, r0 /* incremment */ + ori r4, r0, TOPHYS(_fdt_start) /* save bram context */ + ori r3, r0, (0x4000 - 4) +_copy_fdt: + lw r12, r7, r11 /* r12 = r7 + r11 */ + sw r12, r4, r11 /* addr[r4 + r11] = r12 */ + addik r11, r11, 4 /* increment counting */ + bgtid r3, _copy_fdt /* loop for all entries */ + addik r3, r3, -4 /* descrement loop */ +no_fdt_arg: + + /* Initialize small data anchors */ + la r13, r0, _KERNEL_SDA_BASE_ + la r2, r0, _KERNEL_SDA2_BASE_ + + /* Initialize stack pointer */ + la r1, r0, init_thread_union + THREAD_SIZE - 4 + + /* Initialize r31 with current task address */ + la r31, r0, init_task + + /* + * Call platform dependent initialize function. + * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for + * the function. + */ + la r8, r0, machine_early_init + brald r15, r8 + nop + + la r15, r0, machine_halt + braid start_kernel + nop diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c new file mode 100644 index 0000000..1bdf202 --- /dev/null +++ b/arch/microblaze/kernel/heartbeat.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sched.h> +#include <linux/io.h> + +#include <asm/setup.h> +#include <asm/page.h> +#include <asm/prom.h> + +static unsigned int base_addr; + +void heartbeat(void) +{ + static unsigned int cnt, period, dist; + + if (base_addr) { + if (cnt == 0 || cnt == dist) + out_be32(base_addr, 1); + else if (cnt == 7 || cnt == dist + 7) + out_be32(base_addr, 0); + + if (++cnt > period) { + cnt = 0; + /* + * The hyperbolic function below modifies the heartbeat + * period length in dependency of the current (5min) + * load. It goes through the points f(0)=126, f(1)=86, + * f(5)=51, f(inf)->30. + */ + period = ((672 << FSHIFT) / (5 * avenrun[0] + + (7 << FSHIFT))) + 30; + dist = period / 4; + } + } +} + +void setup_heartbeat(void) +{ + struct device_node *gpio = NULL; + int j; + char *gpio_list[] = { + "xlnx,xps-gpio-1.00.a", + "xlnx,opb-gpio-1.00.a", + NULL + }; + + for (j = 0; gpio_list[j] != NULL; j++) { + gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]); + if (gpio) + break; + } + + base_addr = *(int *) of_get_property(gpio, "reg", NULL); + base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE); + printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr); + + if (*(int *) of_get_property(gpio, "xlnx,is-bidir", NULL)) + out_be32(base_addr + 4, 0); /* GPIO is configured as output */ +} diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S new file mode 100644 index 0000000..cf9486d --- /dev/null +++ b/arch/microblaze/kernel/hw_exception_handler.S @@ -0,0 +1,458 @@ +/* + * Exception handling for Microblaze + * + * Rewriten interrupt handling + * + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * + * uClinux customisation (C) 2005 John Williams + * + * MMU code derived from arch/ppc/kernel/head_4xx.S: + * Copyright (C) 1995-1996 Gary Thomas <gdt@linuxppc.org> + * Initial PowerPC version. + * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> + * Rewritten for PReP + * Copyright (C) 1996 Paul Mackerras <paulus@cs.anu.edu.au> + * Low-level exception handers, MMU support, and rewrite. + * Copyright (C) 1997 Dan Malek <dmalek@jlc.net> + * PowerPC 8xx modifications. + * Copyright (C) 1998-1999 TiVo, Inc. + * PowerPC 403GCX modifications. + * Copyright (C) 1999 Grant Erickson <grant@lcse.umn.edu> + * PowerPC 403GCX/405GP modifications. + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * PowerPC 403GCX/405GP modifications. + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * + * Original code + * Copyright (C) 2004 Xilinx, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +/* + * Here are the handlers which don't require enabling translation + * and calling other kernel code thus we can keep their design very simple + * and do all processing in real mode. All what they need is a valid current + * (that is an issue for the CONFIG_REGISTER_TASK_PTR case) + * This handlers use r3,r4,r5,r6 and optionally r[current] to work therefore + * these registers are saved/restored + * The handlers which require translation are in entry.S --KAA + * + * Microblaze HW Exception Handler + * - Non self-modifying exception handler for the following exception conditions + * - Unalignment + * - Instruction bus error + * - Data bus error + * - Illegal instruction opcode + * - Divide-by-zero + * + * Note we disable interrupts during exception handling, otherwise we will + * possibly get multiple re-entrancy if interrupt handles themselves cause + * exceptions. JW + */ + +#include <asm/exceptions.h> +#include <asm/unistd.h> +#include <asm/page.h> + +#include <asm/entry.h> +#include <asm/current.h> +#include <linux/linkage.h> + +#include <asm/mmu.h> +#include <asm/pgtable.h> +#include <asm/asm-offsets.h> + +/* Helpful Macros */ +#define EX_HANDLER_STACK_SIZ (4*19) +#define NUM_TO_REG(num) r ## num + +#define LWREG_NOP \ + bri ex_handler_unhandled; \ + nop; + +#define SWREG_NOP \ + bri ex_handler_unhandled; \ + nop; + +/* FIXME this is weird - for noMMU kernel is not possible to use brid + * instruction which can shorten executed time + */ + +/* r3 is the source */ +#define R3_TO_LWREG_V(regnum) \ + swi r3, r1, 4 * regnum; \ + bri ex_handler_done; + +/* r3 is the source */ +#define R3_TO_LWREG(regnum) \ + or NUM_TO_REG (regnum), r0, r3; \ + bri ex_handler_done; + +/* r3 is the target */ +#define SWREG_TO_R3_V(regnum) \ + lwi r3, r1, 4 * regnum; \ + bri ex_sw_tail; + +/* r3 is the target */ +#define SWREG_TO_R3(regnum) \ + or r3, r0, NUM_TO_REG (regnum); \ + bri ex_sw_tail; + +.extern other_exception_handler /* Defined in exception.c */ + +/* + * hw_exception_handler - Handler for exceptions + * + * Exception handler notes: + * - Handles all exceptions + * - Does not handle unaligned exceptions during load into r17, r1, r0. + * - Does not handle unaligned exceptions during store from r17 (cannot be + * done) and r1 (slows down common case) + * + * Relevant register structures + * + * EAR - |----|----|----|----|----|----|----|----| + * - < ## 32 bit faulting address ## > + * + * ESR - |----|----|----|----|----| - | - |-----|-----| + * - W S REG EXC + * + * + * STACK FRAME STRUCTURE (for NO_MMU) + * --------------------------------- + * + * +-------------+ + 0 + * | MSR | + * +-------------+ + 4 + * | r1 | + * | . | + * | . | + * | . | + * | . | + * | r18 | + * +-------------+ + 76 + * | . | + * | . | + * + * NO_MMU kernel use the same r0_ram pointed space - look to vmlinux.lds.S + * which is used for storing register values - old style was, that value were + * stored in stack but in case of failure you lost information about register. + * Currently you can see register value in memory in specific place. + * In compare to with previous solution the speed should be the same. + * + * MMU exception handler has different handling compare to no MMU kernel. + * Exception handler use jump table for directing of what happen. For MMU kernel + * is this approach better because MMU relate exception are handled by asm code + * in this file. In compare to with MMU expect of unaligned exception + * is everything handled by C code. + */ + +/* + * every of these handlers is entered having R3/4/5/6/11/current saved on stack + * and clobbered so care should be taken to restore them if someone is going to + * return from exception + */ + +/* wrappers to restore state before coming to entry.S */ + +.global _hw_exception_handler +.section .text +.align 4 +.ent _hw_exception_handler +_hw_exception_handler: + addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */ + swi r3, r1, PT_R3 + swi r4, r1, PT_R4 + swi r5, r1, PT_R5 + swi r6, r1, PT_R6 + + mfs r5, rmsr; + nop + swi r5, r1, 0; + mfs r4, rbtr /* Save BTR before jumping to handler */ + nop + mfs r3, resr + nop + + andi r5, r3, 0x1000; /* Check ESR[DS] */ + beqi r5, not_in_delay_slot; /* Branch if ESR[DS] not set */ + mfs r17, rbtr; /* ESR[DS] set - return address in BTR */ + nop +not_in_delay_slot: + swi r17, r1, PT_R17 + + andi r5, r3, 0x1F; /* Extract ESR[EXC] */ + + /* Exceptions enabled here. This will allow nested exceptions */ + mfs r6, rmsr; + nop + swi r6, r1, 0; /* RMSR_OFFSET */ + ori r6, r6, 0x100; /* Turn ON the EE bit */ + andi r6, r6, ~2; /* Disable interrupts */ + mts rmsr, r6; + nop + + xori r6, r5, 1; /* 00001 = Unaligned Exception */ + /* Jump to unalignment exception handler */ + beqi r6, handle_unaligned_ex; + +handle_other_ex: /* Handle Other exceptions here */ + /* Save other volatiles before we make procedure calls below */ + swi r7, r1, PT_R7 + swi r8, r1, PT_R8 + swi r9, r1, PT_R9 + swi r10, r1, PT_R10 + swi r11, r1, PT_R11 + swi r12, r1, PT_R12 + swi r14, r1, PT_R14 + swi r15, r1, PT_R15 + swi r18, r1, PT_R18 + + or r5, r1, r0 + andi r6, r3, 0x1F; /* Load ESR[EC] */ + lwi r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */ + swi r7, r1, PT_MODE + mfs r7, rfsr + nop + addk r8, r17, r0; /* Load exception address */ + bralid r15, full_exception; /* Branch to the handler */ + nop; + + /* + * Trigger execution of the signal handler by enabling + * interrupts and calling an invalid syscall. + */ + mfs r5, rmsr; + nop + ori r5, r5, 2; + mts rmsr, r5; /* enable interrupt */ + nop + addi r12, r0, __NR_syscalls; + brki r14, 0x08; + mfs r5, rmsr; /* disable interrupt */ + nop + andi r5, r5, ~2; + mts rmsr, r5; + nop + + lwi r7, r1, PT_R7 + lwi r8, r1, PT_R8 + lwi r9, r1, PT_R9 + lwi r10, r1, PT_R10 + lwi r11, r1, PT_R11 + lwi r12, r1, PT_R12 + lwi r14, r1, PT_R14 + lwi r15, r1, PT_R15 + lwi r18, r1, PT_R18 + + bri ex_handler_done; /* Complete exception handling */ + +/* 0x01 - Unaligned data access exception + * This occurs when a word access is not aligned on a word boundary, + * or when a 16-bit access is not aligned on a 16-bit boundary. + * This handler perform the access, and returns, except for MMU when + * the unaligned address is last on a 4k page or the physical address is + * not found in the page table, in which case unaligned_data_trap is called. + */ +handle_unaligned_ex: + /* Working registers already saved: R3, R4, R5, R6 + * R3 = ESR + * R4 = BTR + */ + mfs r4, rear; + nop + + andi r6, r3, 0x3E0; /* Mask and extract the register operand */ + srl r6, r6; /* r6 >> 5 */ + srl r6, r6; + srl r6, r6; + srl r6, r6; + srl r6, r6; + /* Store the register operand in a temporary location */ + sbi r6, r0, TOPHYS(ex_reg_op); + + andi r6, r3, 0x400; /* Extract ESR[S] */ + bnei r6, ex_sw; +ex_lw: + andi r6, r3, 0x800; /* Extract ESR[W] */ + beqi r6, ex_lhw; + lbui r5, r4, 0; /* Exception address in r4 */ + /* Load a word, byte-by-byte from destination address + and save it in tmp space */ + sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); + lbui r5, r4, 1; + sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); + lbui r5, r4, 2; + sbi r5, r0, TOPHYS(ex_tmp_data_loc_2); + lbui r5, r4, 3; + sbi r5, r0, TOPHYS(ex_tmp_data_loc_3); + /* Get the destination register value into r3 */ + lwi r3, r0, TOPHYS(ex_tmp_data_loc_0); + bri ex_lw_tail; +ex_lhw: + lbui r5, r4, 0; /* Exception address in r4 */ + /* Load a half-word, byte-by-byte from destination + address and save it in tmp space */ + sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); + lbui r5, r4, 1; + sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); + /* Get the destination register value into r3 */ + lhui r3, r0, TOPHYS(ex_tmp_data_loc_0); +ex_lw_tail: + /* Get the destination register number into r5 */ + lbui r5, r0, TOPHYS(ex_reg_op); + /* Form load_word jump table offset (lw_table + (8 * regnum)) */ + la r6, r0, TOPHYS(lw_table); + addk r5, r5, r5; + addk r5, r5, r5; + addk r5, r5, r5; + addk r5, r5, r6; + bra r5; +ex_lw_end: /* Exception handling of load word, ends */ +ex_sw: + /* Get the destination register number into r5 */ + lbui r5, r0, TOPHYS(ex_reg_op); + /* Form store_word jump table offset (sw_table + (8 * regnum)) */ + la r6, r0, TOPHYS(sw_table); + add r5, r5, r5; + add r5, r5, r5; + add r5, r5, r5; + add r5, r5, r6; + bra r5; +ex_sw_tail: + mfs r6, resr; + nop + andi r6, r6, 0x800; /* Extract ESR[W] */ + beqi r6, ex_shw; + /* Get the word - delay slot */ + swi r3, r0, TOPHYS(ex_tmp_data_loc_0); + /* Store the word, byte-by-byte into destination address */ + lbui r3, r0, TOPHYS(ex_tmp_data_loc_0); + sbi r3, r4, 0; + lbui r3, r0, TOPHYS(ex_tmp_data_loc_1); + sbi r3, r4, 1; + lbui r3, r0, TOPHYS(ex_tmp_data_loc_2); + sbi r3, r4, 2; + lbui r3, r0, TOPHYS(ex_tmp_data_loc_3); + sbi r3, r4, 3; + bri ex_handler_done; + +ex_shw: + /* Store the lower half-word, byte-by-byte into destination address */ + swi r3, r0, TOPHYS(ex_tmp_data_loc_0); + lbui r3, r0, TOPHYS(ex_tmp_data_loc_2); + sbi r3, r4, 0; + lbui r3, r0, TOPHYS(ex_tmp_data_loc_3); + sbi r3, r4, 1; +ex_sw_end: /* Exception handling of store word, ends. */ + +ex_handler_done: + lwi r5, r1, 0 /* RMSR */ + mts rmsr, r5 + nop + lwi r3, r1, PT_R3 + lwi r4, r1, PT_R4 + lwi r5, r1, PT_R5 + lwi r6, r1, PT_R6 + lwi r17, r1, PT_R17 + + rted r17, 0 + addik r1, r1, (EX_HANDLER_STACK_SIZ); /* Restore stack frame */ + +.end _hw_exception_handler + +ex_handler_unhandled: +/* FIXME add handle function for unhandled exception - dump register */ + bri 0 + +.section .text +.align 4 +lw_table: +lw_r0: R3_TO_LWREG (0); +lw_r1: LWREG_NOP; +lw_r2: R3_TO_LWREG (2); +lw_r3: R3_TO_LWREG_V (3); +lw_r4: R3_TO_LWREG_V (4); +lw_r5: R3_TO_LWREG_V (5); +lw_r6: R3_TO_LWREG_V (6); +lw_r7: R3_TO_LWREG (7); +lw_r8: R3_TO_LWREG (8); +lw_r9: R3_TO_LWREG (9); +lw_r10: R3_TO_LWREG (10); +lw_r11: R3_TO_LWREG (11); +lw_r12: R3_TO_LWREG (12); +lw_r13: R3_TO_LWREG (13); +lw_r14: R3_TO_LWREG (14); +lw_r15: R3_TO_LWREG (15); +lw_r16: R3_TO_LWREG (16); +lw_r17: LWREG_NOP; +lw_r18: R3_TO_LWREG (18); +lw_r19: R3_TO_LWREG (19); +lw_r20: R3_TO_LWREG (20); +lw_r21: R3_TO_LWREG (21); +lw_r22: R3_TO_LWREG (22); +lw_r23: R3_TO_LWREG (23); +lw_r24: R3_TO_LWREG (24); +lw_r25: R3_TO_LWREG (25); +lw_r26: R3_TO_LWREG (26); +lw_r27: R3_TO_LWREG (27); +lw_r28: R3_TO_LWREG (28); +lw_r29: R3_TO_LWREG (29); +lw_r30: R3_TO_LWREG (30); +lw_r31: R3_TO_LWREG (31); + +sw_table: +sw_r0: SWREG_TO_R3 (0); +sw_r1: SWREG_NOP; +sw_r2: SWREG_TO_R3 (2); +sw_r3: SWREG_TO_R3_V (3); +sw_r4: SWREG_TO_R3_V (4); +sw_r5: SWREG_TO_R3_V (5); +sw_r6: SWREG_TO_R3_V (6); +sw_r7: SWREG_TO_R3 (7); +sw_r8: SWREG_TO_R3 (8); +sw_r9: SWREG_TO_R3 (9); +sw_r10: SWREG_TO_R3 (10); +sw_r11: SWREG_TO_R3 (11); +sw_r12: SWREG_TO_R3 (12); +sw_r13: SWREG_TO_R3 (13); +sw_r14: SWREG_TO_R3 (14); +sw_r15: SWREG_TO_R3 (15); +sw_r16: SWREG_TO_R3 (16); +sw_r17: SWREG_NOP; +sw_r18: SWREG_TO_R3 (18); +sw_r19: SWREG_TO_R3 (19); +sw_r20: SWREG_TO_R3 (20); +sw_r21: SWREG_TO_R3 (21); +sw_r22: SWREG_TO_R3 (22); +sw_r23: SWREG_TO_R3 (23); +sw_r24: SWREG_TO_R3 (24); +sw_r25: SWREG_TO_R3 (25); +sw_r26: SWREG_TO_R3 (26); +sw_r27: SWREG_TO_R3 (27); +sw_r28: SWREG_TO_R3 (28); +sw_r29: SWREG_TO_R3 (29); +sw_r30: SWREG_TO_R3 (30); +sw_r31: SWREG_TO_R3 (31); + +/* Temporary data structures used in the handler */ +.section .data +.align 4 +ex_tmp_data_loc_0: + .byte 0 +ex_tmp_data_loc_1: + .byte 0 +ex_tmp_data_loc_2: + .byte 0 +ex_tmp_data_loc_3: + .byte 0 +ex_reg_op: + .byte 0 diff --git a/arch/microblaze/kernel/init_task.c b/arch/microblaze/kernel/init_task.c new file mode 100644 index 0000000..48eb9fb --- /dev/null +++ b/arch/microblaze/kernel/init_task.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/init_task.h> +#include <linux/fs.h> +#include <linux/mqueue.h> + +#include <asm/pgtable.h> + +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct mm_struct init_mm = INIT_MM(init_mm); +EXPORT_SYMBOL(init_mm); + +union thread_union init_thread_union + __attribute__((__section__(".data.init_task"))) = +{ INIT_THREAD_INFO(init_task) }; + +struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c new file mode 100644 index 0000000..a69d3e3 --- /dev/null +++ b/arch/microblaze/kernel/intc.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <asm/page.h> +#include <linux/io.h> + +#include <asm/prom.h> +#include <asm/irq.h> + +#ifdef CONFIG_SELFMOD_INTC +#include <asm/selfmod.h> +#define INTC_BASE BARRIER_BASE_ADDR +#else +static unsigned int intc_baseaddr; +#define INTC_BASE intc_baseaddr +#endif + +unsigned int nr_irq; + +/* No one else should require these constants, so define them locally here. */ +#define ISR 0x00 /* Interrupt Status Register */ +#define IPR 0x04 /* Interrupt Pending Register */ +#define IER 0x08 /* Interrupt Enable Register */ +#define IAR 0x0c /* Interrupt Acknowledge Register */ +#define SIE 0x10 /* Set Interrupt Enable bits */ +#define CIE 0x14 /* Clear Interrupt Enable bits */ +#define IVR 0x18 /* Interrupt Vector Register */ +#define MER 0x1c /* Master Enable Register */ + +#define MER_ME (1<<0) +#define MER_HIE (1<<1) + +static void intc_enable_or_unmask(unsigned int irq) +{ + pr_debug("enable_or_unmask: %d\n", irq); + out_be32(INTC_BASE + SIE, 1 << irq); +} + +static void intc_disable_or_mask(unsigned int irq) +{ + pr_debug("disable: %d\n", irq); + out_be32(INTC_BASE + CIE, 1 << irq); +} + +static void intc_ack(unsigned int irq) +{ + pr_debug("ack: %d\n", irq); + out_be32(INTC_BASE + IAR, 1 << irq); +} + +static void intc_mask_ack(unsigned int irq) +{ + unsigned long mask = 1 << irq; + pr_debug("disable_and_ack: %d\n", irq); + out_be32(INTC_BASE + CIE, mask); + out_be32(INTC_BASE + IAR, mask); +} + +static void intc_end(unsigned int irq) +{ + unsigned long mask = 1 << irq; + pr_debug("end: %d\n", irq); + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + out_be32(INTC_BASE + SIE, mask); + /* ack level sensitive intr */ + if (irq_desc[irq].status & IRQ_LEVEL) + out_be32(INTC_BASE + IAR, mask); + } +} + +static struct irq_chip intc_dev = { + .name = "Xilinx INTC", + .unmask = intc_enable_or_unmask, + .mask = intc_disable_or_mask, + .ack = intc_ack, + .mask_ack = intc_mask_ack, + .end = intc_end, +}; + +unsigned int get_irq(struct pt_regs *regs) +{ + int irq; + + /* + * NOTE: This function is the one that needs to be improved in + * order to handle multiple interrupt controllers. It currently + * is hardcoded to check for interrupts only on the first INTC. + */ + irq = in_be32(INTC_BASE + IVR); + pr_debug("get_irq: %d\n", irq); + + return irq; +} + +void __init init_IRQ(void) +{ + u32 i, j, intr_type; + struct device_node *intc = NULL; +#ifdef CONFIG_SELFMOD_INTC + unsigned int intc_baseaddr = 0; + static int arr_func[] = { + (int)&get_irq, + (int)&intc_enable_or_unmask, + (int)&intc_disable_or_mask, + (int)&intc_mask_ack, + (int)&intc_ack, + (int)&intc_end, + 0 + }; +#endif + static char *intc_list[] = { + "xlnx,xps-intc-1.00.a", + "xlnx,opb-intc-1.00.c", + "xlnx,opb-intc-1.00.b", + "xlnx,opb-intc-1.00.a", + NULL + }; + + for (j = 0; intc_list[j] != NULL; j++) { + intc = of_find_compatible_node(NULL, NULL, intc_list[j]); + if (intc) + break; + } + + intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL); + intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); + nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL); + + intr_type = + *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); + if (intr_type >= (1 << nr_irq)) + printk(KERN_INFO " ERROR: Mishmash in king-of-intr param\n"); + +#ifdef CONFIG_SELFMOD_INTC + selfmod_function((int *) arr_func, intc_baseaddr); +#endif + printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n", + intc_list[j], intc_baseaddr, nr_irq, intr_type); + + /* + * Disable all external interrupts until they are + * explicity requested. + */ + out_be32(intc_baseaddr + IER, 0); + + /* Acknowledge any pending interrupts just in case. */ + out_be32(intc_baseaddr + IAR, 0xffffffff); + + /* Turn on the Master Enable. */ + out_be32(intc_baseaddr + MER, MER_HIE | MER_ME); + + for (i = 0; i < nr_irq; ++i) { + if (intr_type & (0x00000001 << i)) { + set_irq_chip_and_handler_name(i, &intc_dev, + handle_edge_irq, intc_dev.name); + irq_desc[i].status &= ~IRQ_LEVEL; + } else { + set_irq_chip_and_handler_name(i, &intc_dev, + handle_level_irq, intc_dev.name); + irq_desc[i].status |= IRQ_LEVEL; + } + } +} diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c new file mode 100644 index 0000000..f688ee9 --- /dev/null +++ b/arch/microblaze/kernel/irq.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/hardirq.h> +#include <linux/interrupt.h> +#include <linux/irqflags.h> +#include <linux/seq_file.h> +#include <linux/kernel_stat.h> +#include <linux/irq.h> + +#include <asm/prom.h> + +unsigned int irq_of_parse_and_map(struct device_node *dev, int index) +{ + struct of_irq oirq; + + if (of_irq_map_one(dev, index, &oirq)) + return NO_IRQ; + + return oirq.specifier[0]; +} +EXPORT_SYMBOL_GPL(irq_of_parse_and_map); + +/* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves. + */ +void ack_bad_irq(unsigned int irq) +{ + printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq); +} + +static u32 concurrent_irq; + +void do_IRQ(struct pt_regs *regs) +{ + unsigned int irq; + struct pt_regs *old_regs = set_irq_regs(regs); + + irq_enter(); + irq = get_irq(regs); +next_irq: + BUG_ON(irq == -1U); + generic_handle_irq(irq); + + irq = get_irq(regs); + if (irq != -1U) { + pr_debug("next irq: %d\n", irq); + ++concurrent_irq; + goto next_irq; + } + + irq_exit(); + set_irq_regs(old_regs); +} + +int show_interrupts(struct seq_file *p, void *v) +{ + int i = *(loff_t *) v, j; + struct irqaction *action; + unsigned long flags; + + if (i == 0) { + seq_printf(p, " "); + for_each_online_cpu(j) + seq_printf(p, "CPU%-8d", j); + seq_putc(p, '\n'); + } + + if (i < nr_irq) { + spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (!action) + goto skip; + seq_printf(p, "%3d: ", i); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for_each_online_cpu(j) + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); +#endif + seq_printf(p, " %8s", irq_desc[i].status & + IRQ_LEVEL ? "level" : "edge"); + seq_printf(p, " %8s", irq_desc[i].chip->name); + seq_printf(p, " %s", action->name); + + for (action = action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } + return 0; +} diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c new file mode 100644 index 0000000..5f71790 --- /dev/null +++ b/arch/microblaze/kernel/microblaze_ksyms.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/string.h> +#include <linux/cryptohash.h> +#include <linux/delay.h> +#include <linux/in6.h> +#include <linux/syscalls.h> + +#include <asm/checksum.h> +#include <linux/io.h> +#include <asm/page.h> +#include <asm/system.h> +#include <linux/uaccess.h> + +/* + * libgcc functions - functions that are used internally by the + * compiler... (prototypes are not correct though, but that + * doesn't really matter since they're not versioned). + */ +extern void __ashldi3(void); +EXPORT_SYMBOL(__ashldi3); +extern void __ashrdi3(void); +EXPORT_SYMBOL(__ashrdi3); +extern void __divsi3(void); +EXPORT_SYMBOL(__divsi3); +extern void __lshrdi3(void); +EXPORT_SYMBOL(__lshrdi3); +extern void __modsi3(void); +EXPORT_SYMBOL(__modsi3); +extern void __mulsi3(void); +EXPORT_SYMBOL(__mulsi3); +extern void __muldi3(void); +EXPORT_SYMBOL(__muldi3); +extern void __ucmpdi2(void); +EXPORT_SYMBOL(__ucmpdi2); +extern void __udivsi3(void); +EXPORT_SYMBOL(__udivsi3); +extern void __umodsi3(void); +EXPORT_SYMBOL(__umodsi3); diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c new file mode 100644 index 0000000..5141417 --- /dev/null +++ b/arch/microblaze/kernel/module.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/moduleloader.h> +#include <linux/kernel.h> +#include <linux/elf.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <linux/string.h> + +#include <asm/pgtable.h> + +void *module_alloc(unsigned long size) +{ + void *ret; + ret = (size == 0) ? NULL : vmalloc(size); + pr_debug("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret); + return ret; +} + +void module_free(struct module *module, void *region) +{ + pr_debug("module_free(%s,%08lx)\n", module->name, + (unsigned long)region); + vfree(region); +} + +int module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) +{ + return 0; +} + +int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, + unsigned int symindex, unsigned int relsec, struct module *module) +{ + printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", + module->name); + return -ENOEXEC; +} + +int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, + unsigned int symindex, unsigned int relsec, struct module *module) +{ + + unsigned int i; + Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; + Elf32_Sym *sym; + unsigned long int *location; + unsigned long int locoffs; + unsigned long int value; +#if __GNUC__ < 4 + unsigned long int old_value; +#endif + + pr_debug("Applying add relocation section %u to %u\n", + relsec, sechdrs[relsec].sh_info); + + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { + + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + + rela[i].r_offset; + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr + + ELF32_R_SYM(rela[i].r_info); + value = sym->st_value + rela[i].r_addend; + + switch (ELF32_R_TYPE(rela[i].r_info)) { + + /* + * Be careful! mb-gcc / mb-ld splits the relocs between the + * text and the reloc table. In general this means we must + * read the current contents of (*location), add any offset + * then store the result back in + */ + + case R_MICROBLAZE_32: +#if __GNUC__ < 4 + old_value = *location; + *location = value + old_value; + + pr_debug("R_MICROBLAZE_32 (%08lx->%08lx)\n", + old_value, value); +#else + *location = value; +#endif + break; + + case R_MICROBLAZE_64: +#if __GNUC__ < 4 + /* Split relocs only required/used pre gcc4.1.1 */ + old_value = ((location[0] & 0x0000FFFF) << 16) | + (location[1] & 0x0000FFFF); + value += old_value; +#endif + location[0] = (location[0] & 0xFFFF0000) | + (value >> 16); + location[1] = (location[1] & 0xFFFF0000) | + (value & 0xFFFF); +#if __GNUC__ < 4 + pr_debug("R_MICROBLAZE_64 (%08lx->%08lx)\n", + old_value, value); +#endif + break; + + case R_MICROBLAZE_64_PCREL: + locoffs = (location[0] & 0xFFFF) << 16 | + (location[1] & 0xFFFF); + value -= (unsigned long int)(location) + 4 + + locoffs; + location[0] = (location[0] & 0xFFFF0000) | + (value >> 16); + location[1] = (location[1] & 0xFFFF0000) | + (value & 0xFFFF); + pr_debug("R_MICROBLAZE_64_PCREL (%08lx)\n", + value); + break; + + case R_MICROBLAZE_NONE: + pr_debug("R_MICROBLAZE_NONE\n"); + break; + + default: + printk(KERN_ERR "module %s: " + "Unknown relocation: %u\n", + module->name, + ELF32_R_TYPE(rela->r_info)); + return -ENOEXEC; + } + } + return 0; +} + +int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, + struct module *module) +{ + return 0; +} + +void module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c new file mode 100644 index 0000000..9a0f763 --- /dev/null +++ b/arch/microblaze/kernel/of_device.c @@ -0,0 +1,113 @@ +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/slab.h> +#include <linux/of_device.h> + +#include <linux/errno.h> + +void of_device_make_bus_id(struct of_device *dev) +{ + static atomic_t bus_no_reg_magic; + struct device_node *node = dev->node; + const u32 *reg; + u64 addr; + int magic; + + /* + * For MMIO, get the physical address + */ + reg = of_get_property(node, "reg", NULL); + if (reg) { + addr = of_translate_address(node, reg); + if (addr != OF_BAD_ADDR) { + dev_set_name(&dev->dev, "%llx.%s", + (unsigned long long)addr, node->name); + return; + } + } + + /* + * No BusID, use the node name and add a globally incremented + * counter (and pray...) + */ + magic = atomic_add_return(1, &bus_no_reg_magic); + dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1); +} +EXPORT_SYMBOL(of_device_make_bus_id); + +struct of_device *of_device_alloc(struct device_node *np, + const char *bus_id, + struct device *parent) +{ + struct of_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->node = of_node_get(np); + dev->dev.dma_mask = &dev->dma_mask; + dev->dev.parent = parent; + dev->dev.release = of_release_dev; + dev->dev.archdata.of_node = np; + + if (bus_id) + dev_set_name(&dev->dev, bus_id); + else + of_device_make_bus_id(dev); + + return dev; +} +EXPORT_SYMBOL(of_device_alloc); + +int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct of_device *ofdev; + const char *compat; + int seen = 0, cplen, sl; + + if (!dev) + return -ENODEV; + + ofdev = to_of_device(dev); + + if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) + return -ENOMEM; + + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) + return -ENOMEM; + + /* Since the compatible field can contain pretty much anything + * it's not really legal to split it out with commas. We split it + * up using a number of environment variables instead. */ + + compat = of_get_property(ofdev->node, "compatible", &cplen); + while (compat && *compat && cplen > 0) { + if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) + return -ENOMEM; + + sl = strlen(compat) + 1; + compat += sl; + cplen -= sl; + seen++; + } + + if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) + return -ENOMEM; + + /* modalias is trickier, we add it in 2 steps */ + if (add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], + sizeof(env->buf) - env->buflen); + if (sl >= (sizeof(env->buf) - env->buflen)) + return -ENOMEM; + env->buflen += sl; + + return 0; +} +EXPORT_SYMBOL(of_device_uevent); diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c new file mode 100644 index 0000000..acf4574 --- /dev/null +++ b/arch/microblaze/kernel/of_platform.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. + * <benh@kernel.crashing.org> + * and Arnd Bergmann, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#undef DEBUG + +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/slab.h> +#include <linux/pci.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> + +#include <linux/errno.h> +#include <linux/topology.h> +#include <asm/atomic.h> + +struct bus_type of_platform_bus_type = { + .uevent = of_device_uevent, +}; +EXPORT_SYMBOL(of_platform_bus_type); + +static int __init of_bus_driver_init(void) +{ + return of_bus_type_init(&of_platform_bus_type, "of_platform"); +} +postcore_initcall(of_bus_driver_init); + +struct of_device *of_platform_device_create(struct device_node *np, + const char *bus_id, + struct device *parent) +{ + struct of_device *dev; + + dev = of_device_alloc(np, bus_id, parent); + if (!dev) + return NULL; + + dev->dma_mask = 0xffffffffUL; + dev->dev.bus = &of_platform_bus_type; + + /* We do not fill the DMA ops for platform devices by default. + * This is currently the responsibility of the platform code + * to do such, possibly using a device notifier + */ + + if (of_device_register(dev) != 0) { + of_device_free(dev); + return NULL; + } + + return dev; +} +EXPORT_SYMBOL(of_platform_device_create); + +/** + * of_platform_bus_create - Create an OF device for a bus node and all its + * children. Optionally recursively instanciate matching busses. + * @bus: device node of the bus to instanciate + * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to + * disallow recursive creation of child busses + */ +static int of_platform_bus_create(const struct device_node *bus, + const struct of_device_id *matches, + struct device *parent) +{ + struct device_node *child; + struct of_device *dev; + int rc = 0; + + for_each_child_of_node(bus, child) { + pr_debug(" create child: %s\n", child->full_name); + dev = of_platform_device_create(child, NULL, parent); + if (dev == NULL) + rc = -ENOMEM; + else if (!of_match_node(matches, child)) + continue; + if (rc == 0) { + pr_debug(" and sub busses\n"); + rc = of_platform_bus_create(child, matches, &dev->dev); + } + if (rc) { + of_node_put(child); + break; + } + } + return rc; +} + + +/** + * of_platform_bus_probe - Probe the device-tree for platform busses + * @root: parent of the first level to probe or NULL for the root of the tree + * @matches: match table, NULL to use the default + * @parent: parent to hook devices from, NULL for toplevel + * + * Note that children of the provided root are not instanciated as devices + * unless the specified root itself matches the bus list and is not NULL. + */ + +int of_platform_bus_probe(struct device_node *root, + const struct of_device_id *matches, + struct device *parent) +{ + struct device_node *child; + struct of_device *dev; + int rc = 0; + + if (matches == NULL) + matches = of_default_bus_ids; + if (matches == OF_NO_DEEP_PROBE) + return -EINVAL; + if (root == NULL) + root = of_find_node_by_path("/"); + else + of_node_get(root); + + pr_debug("of_platform_bus_probe()\n"); + pr_debug(" starting at: %s\n", root->full_name); + + /* Do a self check of bus type, if there's a match, create + * children + */ + if (of_match_node(matches, root)) { + pr_debug(" root match, create all sub devices\n"); + dev = of_platform_device_create(root, NULL, parent); + if (dev == NULL) { + rc = -ENOMEM; + goto bail; + } + pr_debug(" create all sub busses\n"); + rc = of_platform_bus_create(root, matches, &dev->dev); + goto bail; + } + for_each_child_of_node(root, child) { + if (!of_match_node(matches, child)) + continue; + + pr_debug(" match: %s\n", child->full_name); + dev = of_platform_device_create(child, NULL, parent); + if (dev == NULL) + rc = -ENOMEM; + else + rc = of_platform_bus_create(child, matches, &dev->dev); + if (rc) { + of_node_put(child); + break; + } + } + bail: + of_node_put(root); + return rc; +} +EXPORT_SYMBOL(of_platform_bus_probe); + +static int of_dev_node_match(struct device *dev, void *data) +{ + return to_of_device(dev)->node == data; +} + +struct of_device *of_find_device_by_node(struct device_node *np) +{ + struct device *dev; + + dev = bus_find_device(&of_platform_bus_type, + NULL, np, of_dev_node_match); + if (dev) + return to_of_device(dev); + return NULL; +} +EXPORT_SYMBOL(of_find_device_by_node); + +static int of_dev_phandle_match(struct device *dev, void *data) +{ + phandle *ph = data; + return to_of_device(dev)->node->linux_phandle == *ph; +} + +struct of_device *of_find_device_by_phandle(phandle ph) +{ + struct device *dev; + + dev = bus_find_device(&of_platform_bus_type, + NULL, &ph, of_dev_phandle_match); + if (dev) + return to_of_device(dev); + return NULL; +} +EXPORT_SYMBOL(of_find_device_by_phandle); diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c new file mode 100644 index 0000000..436f26c --- /dev/null +++ b/arch/microblaze/kernel/process.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/pm.h> +#include <linux/tick.h> +#include <linux/bitops.h> +#include <asm/system.h> +#include <asm/pgalloc.h> + +void show_regs(struct pt_regs *regs) +{ + printk(KERN_INFO " Registers dump: mode=%X\r\n", regs->kernel_mode); + printk(KERN_INFO " r1=%08lX, r2=%08lX, r3=%08lX, r4=%08lX\n", + regs->r1, regs->r2, regs->r3, regs->r4); + printk(KERN_INFO " r5=%08lX, r6=%08lX, r7=%08lX, r8=%08lX\n", + regs->r5, regs->r6, regs->r7, regs->r8); + printk(KERN_INFO " r9=%08lX, r10=%08lX, r11=%08lX, r12=%08lX\n", + regs->r9, regs->r10, regs->r11, regs->r12); + printk(KERN_INFO " r13=%08lX, r14=%08lX, r15=%08lX, r16=%08lX\n", + regs->r13, regs->r14, regs->r15, regs->r16); + printk(KERN_INFO " r17=%08lX, r18=%08lX, r19=%08lX, r20=%08lX\n", + regs->r17, regs->r18, regs->r19, regs->r20); + printk(KERN_INFO " r21=%08lX, r22=%08lX, r23=%08lX, r24=%08lX\n", + regs->r21, regs->r22, regs->r23, regs->r24); + printk(KERN_INFO " r25=%08lX, r26=%08lX, r27=%08lX, r28=%08lX\n", + regs->r25, regs->r26, regs->r27, regs->r28); + printk(KERN_INFO " r29=%08lX, r30=%08lX, r31=%08lX, rPC=%08lX\n", + regs->r29, regs->r30, regs->r31, regs->pc); + printk(KERN_INFO " msr=%08lX, ear=%08lX, esr=%08lX, fsr=%08lX\n", + regs->msr, regs->ear, regs->esr, regs->fsr); + while (1) + ; +} + +void (*pm_idle)(void); +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); + +static int hlt_counter = 1; + +void disable_hlt(void) +{ + hlt_counter++; +} +EXPORT_SYMBOL(disable_hlt); + +void enable_hlt(void) +{ + hlt_counter--; +} +EXPORT_SYMBOL(enable_hlt); + +static int __init nohlt_setup(char *__unused) +{ + hlt_counter = 1; + return 1; +} +__setup("nohlt", nohlt_setup); + +static int __init hlt_setup(char *__unused) +{ + hlt_counter = 0; + return 1; +} +__setup("hlt", hlt_setup); + +void default_idle(void) +{ + if (!hlt_counter) { + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); + local_irq_disable(); + while (!need_resched()) + cpu_sleep(); + local_irq_enable(); + set_thread_flag(TIF_POLLING_NRFLAG); + } else + while (!need_resched()) + cpu_relax(); +} + +void cpu_idle(void) +{ + set_thread_flag(TIF_POLLING_NRFLAG); + + /* endless idle loop with no priority at all */ + while (1) { + void (*idle)(void) = pm_idle; + + if (!idle) + idle = default_idle; + + tick_nohz_stop_sched_tick(1); + while (!need_resched()) + idle(); + tick_nohz_restart_sched_tick(); + + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + check_pgt_cache(); + } +} + +void flush_thread(void) +{ +} + +int copy_thread(unsigned long clone_flags, unsigned long usp, + unsigned long unused, + struct task_struct *p, struct pt_regs *regs) +{ + struct pt_regs *childregs = task_pt_regs(p); + struct thread_info *ti = task_thread_info(p); + + *childregs = *regs; + if (user_mode(regs)) + childregs->r1 = usp; + else + childregs->r1 = ((unsigned long) ti) + THREAD_SIZE; + + memset(&ti->cpu_context, 0, sizeof(struct cpu_context)); + ti->cpu_context.r1 = (unsigned long)childregs; + ti->cpu_context.msr = (unsigned long)childregs->msr; + ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8; + + if (clone_flags & CLONE_SETTLS) + ; + + return 0; +} + +/* + * Return saved PC of a blocked thread. + */ +unsigned long thread_saved_pc(struct task_struct *tsk) +{ + struct cpu_context *ctx = + &(((struct thread_info *)(tsk->stack))->cpu_context); + + /* Check whether the thread is blocked in resume() */ + if (in_sched_functions(ctx->r15)) + return (unsigned long)ctx->r15; + else + return ctx->r14; +} + +static void kernel_thread_helper(int (*fn)(void *), void *arg) +{ + fn(arg); + do_exit(-1); +} + +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + struct pt_regs regs; + int ret; + + memset(®s, 0, sizeof(regs)); + /* store them in non-volatile registers */ + regs.r5 = (unsigned long)fn; + regs.r6 = (unsigned long)arg; + local_save_flags(regs.msr); + regs.pc = (unsigned long)kernel_thread_helper; + regs.kernel_mode = 1; + + ret = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, + ®s, 0, NULL, NULL); + + return ret; +} + +unsigned long get_wchan(struct task_struct *p) +{ +/* TBD (used by procfs) */ + return 0; +} diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c new file mode 100644 index 0000000..34c4871 --- /dev/null +++ b/arch/microblaze/kernel/prom.c @@ -0,0 +1,1146 @@ +/* + * Procedures for creating, accessing and interpreting the device tree. + * + * Paul Mackerras August 1996. + * Copyright (C) 1996-2005 Paul Mackerras. + * + * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. + * {engebret|bergner}@us.ibm.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <stdarg.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/threads.h> +#include <linux/spinlock.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/stringify.h> +#include <linux/delay.h> +#include <linux/initrd.h> +#include <linux/bitops.h> +#include <linux/module.h> +#include <linux/kexec.h> +#include <linux/debugfs.h> +#include <linux/irq.h> +#include <linux/lmb.h> + +#include <asm/prom.h> +#include <asm/page.h> +#include <asm/processor.h> +#include <asm/irq.h> +#include <linux/io.h> +#include <asm/system.h> +#include <asm/mmu.h> +#include <asm/pgtable.h> +#include <asm/sections.h> +#include <asm/pci-bridge.h> + +static int __initdata dt_root_addr_cells; +static int __initdata dt_root_size_cells; + +typedef u32 cell_t; + +static struct boot_param_header *initial_boot_params; + +/* export that to outside world */ +struct device_node *of_chosen; + +static inline char *find_flat_dt_string(u32 offset) +{ + return ((char *)initial_boot_params) + + initial_boot_params->off_dt_strings + offset; +} + +/** + * This function is used to scan the flattened device-tree, it is + * used to extract the memory informations at boot before we can + * unflatten the tree + */ +int __init of_scan_flat_dt(int (*it)(unsigned long node, + const char *uname, int depth, + void *data), + void *data) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + initial_boot_params->off_dt_struct; + int rc = 0; + int depth = -1; + + do { + u32 tag = *((u32 *)p); + char *pathp; + + p += 4; + if (tag == OF_DT_END_NODE) { + depth--; + continue; + } + if (tag == OF_DT_NOP) + continue; + if (tag == OF_DT_END) + break; + if (tag == OF_DT_PROP) { + u32 sz = *((u32 *)p); + p += 8; + if (initial_boot_params->version < 0x10) + p = _ALIGN(p, sz >= 8 ? 8 : 4); + p += sz; + p = _ALIGN(p, 4); + continue; + } + if (tag != OF_DT_BEGIN_NODE) { + printk(KERN_WARNING "Invalid tag %x scanning flattened" + " device tree !\n", tag); + return -EINVAL; + } + depth++; + pathp = (char *)p; + p = _ALIGN(p + strlen(pathp) + 1, 4); + if ((*pathp) == '/') { + char *lp, *np; + for (lp = NULL, np = pathp; *np; np++) + if ((*np) == '/') + lp = np+1; + if (lp != NULL) + pathp = lp; + } + rc = it(p, pathp, depth, data); + if (rc != 0) + break; + } while (1); + + return rc; +} + +unsigned long __init of_get_flat_dt_root(void) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + initial_boot_params->off_dt_struct; + + while (*((u32 *)p) == OF_DT_NOP) + p += 4; + BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE); + p += 4; + return _ALIGN(p + strlen((char *)p) + 1, 4); +} + +/** + * This function can be used within scan_flattened_dt callback to get + * access to properties + */ +void *__init of_get_flat_dt_prop(unsigned long node, const char *name, + unsigned long *size) +{ + unsigned long p = node; + + do { + u32 tag = *((u32 *)p); + u32 sz, noff; + const char *nstr; + + p += 4; + if (tag == OF_DT_NOP) + continue; + if (tag != OF_DT_PROP) + return NULL; + + sz = *((u32 *)p); + noff = *((u32 *)(p + 4)); + p += 8; + if (initial_boot_params->version < 0x10) + p = _ALIGN(p, sz >= 8 ? 8 : 4); + + nstr = find_flat_dt_string(noff); + if (nstr == NULL) { + printk(KERN_WARNING "Can't find property index" + " name !\n"); + return NULL; + } + if (strcmp(name, nstr) == 0) { + if (size) + *size = sz; + return (void *)p; + } + p += sz; + p = _ALIGN(p, 4); + } while (1); +} + +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) +{ + const char *cp; + unsigned long cplen, l; + + cp = of_get_flat_dt_prop(node, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncasecmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} + +static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, + unsigned long align) +{ + void *res; + + *mem = _ALIGN(*mem, align); + res = (void *)*mem; + *mem += size; + + return res; +} + +static unsigned long __init unflatten_dt_node(unsigned long mem, + unsigned long *p, + struct device_node *dad, + struct device_node ***allnextpp, + unsigned long fpsize) +{ + struct device_node *np; + struct property *pp, **prev_pp = NULL; + char *pathp; + u32 tag; + unsigned int l, allocl; + int has_name = 0; + int new_format = 0; + + tag = *((u32 *)(*p)); + if (tag != OF_DT_BEGIN_NODE) { + printk("Weird tag at start of node: %x\n", tag); + return mem; + } + *p += 4; + pathp = (char *)*p; + l = allocl = strlen(pathp) + 1; + *p = _ALIGN(*p + l, 4); + + /* version 0x10 has a more compact unit name here instead of the full + * path. we accumulate the full path size using "fpsize", we'll rebuild + * it later. We detect this because the first character of the name is + * not '/'. + */ + if ((*pathp) != '/') { + new_format = 1; + if (fpsize == 0) { + /* root node: special case. fpsize accounts for path + * plus terminating zero. root node only has '/', so + * fpsize should be 2, but we want to avoid the first + * level nodes to have two '/' so we use fpsize 1 here + */ + fpsize = 1; + allocl = 2; + } else { + /* account for '/' and path size minus terminal 0 + * already in 'l' + */ + fpsize += l; + allocl = fpsize; + } + } + + np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, + __alignof__(struct device_node)); + if (allnextpp) { + memset(np, 0, sizeof(*np)); + np->full_name = ((char *)np) + sizeof(struct device_node); + if (new_format) { + char *p2 = np->full_name; + /* rebuild full path for new format */ + if (dad && dad->parent) { + strcpy(p2, dad->full_name); +#ifdef DEBUG + if ((strlen(p2) + l + 1) != allocl) { + pr_debug("%s: p: %d, l: %d, a: %d\n", + pathp, (int)strlen(p2), + l, allocl); + } +#endif + p2 += strlen(p2); + } + *(p2++) = '/'; + memcpy(p2, pathp, l); + } else + memcpy(np->full_name, pathp, l); + prev_pp = &np->properties; + **allnextpp = np; + *allnextpp = &np->allnext; + if (dad != NULL) { + np->parent = dad; + /* we temporarily use the next field as `last_child'*/ + if (dad->next == NULL) + dad->child = np; + else + dad->next->sibling = np; + dad->next = np; + } + kref_init(&np->kref); + } + while (1) { + u32 sz, noff; + char *pname; + + tag = *((u32 *)(*p)); + if (tag == OF_DT_NOP) { + *p += 4; + continue; + } + if (tag != OF_DT_PROP) + break; + *p += 4; + sz = *((u32 *)(*p)); + noff = *((u32 *)((*p) + 4)); + *p += 8; + if (initial_boot_params->version < 0x10) + *p = _ALIGN(*p, sz >= 8 ? 8 : 4); + + pname = find_flat_dt_string(noff); + if (pname == NULL) { + printk(KERN_INFO + "Can't find property name in list !\n"); + break; + } + if (strcmp(pname, "name") == 0) + has_name = 1; + l = strlen(pname) + 1; + pp = unflatten_dt_alloc(&mem, sizeof(struct property), + __alignof__(struct property)); + if (allnextpp) { + if (strcmp(pname, "linux,phandle") == 0) { + np->node = *((u32 *)*p); + if (np->linux_phandle == 0) + np->linux_phandle = np->node; + } + if (strcmp(pname, "ibm,phandle") == 0) + np->linux_phandle = *((u32 *)*p); + pp->name = pname; + pp->length = sz; + pp->value = (void *)*p; + *prev_pp = pp; + prev_pp = &pp->next; + } + *p = _ALIGN((*p) + sz, 4); + } + /* with version 0x10 we may not have the name property, recreate + * it here from the unit name if absent + */ + if (!has_name) { + char *p1 = pathp, *ps = pathp, *pa = NULL; + int sz; + + while (*p1) { + if ((*p1) == '@') + pa = p1; + if ((*p1) == '/') + ps = p1 + 1; + p1++; + } + if (pa < ps) + pa = p1; + sz = (pa - ps) + 1; + pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, + __alignof__(struct property)); + if (allnextpp) { + pp->name = "name"; + pp->length = sz; + pp->value = pp + 1; + *prev_pp = pp; + prev_pp = &pp->next; + memcpy(pp->value, ps, sz - 1); + ((char *)pp->value)[sz - 1] = 0; + pr_debug("fixed up name for %s -> %s\n", pathp, + (char *)pp->value); + } + } + if (allnextpp) { + *prev_pp = NULL; + np->name = of_get_property(np, "name", NULL); + np->type = of_get_property(np, "device_type", NULL); + + if (!np->name) + np->name = "<NULL>"; + if (!np->type) + np->type = "<NULL>"; + } + while (tag == OF_DT_BEGIN_NODE) { + mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); + tag = *((u32 *)(*p)); + } + if (tag != OF_DT_END_NODE) { + printk(KERN_INFO "Weird tag at end of node: %x\n", tag); + return mem; + } + *p += 4; + return mem; +} + +/** + * unflattens the device-tree passed by the firmware, creating the + * tree of struct device_node. It also fills the "name" and "type" + * pointers of the nodes so the normal device-tree walking functions + * can be used (this used to be done by finish_device_tree) + */ +void __init unflatten_device_tree(void) +{ + unsigned long start, mem, size; + struct device_node **allnextp = &allnodes; + + pr_debug(" -> unflatten_device_tree()\n"); + + /* First pass, scan for size */ + start = ((unsigned long)initial_boot_params) + + initial_boot_params->off_dt_struct; + size = unflatten_dt_node(0, &start, NULL, NULL, 0); + size = (size | 3) + 1; + + pr_debug(" size is %lx, allocating...\n", size); + + /* Allocate memory for the expanded device tree */ + mem = lmb_alloc(size + 4, __alignof__(struct device_node)); + mem = (unsigned long) __va(mem); + + ((u32 *)mem)[size / 4] = 0xdeadbeef; + + pr_debug(" unflattening %lx...\n", mem); + + /* Second pass, do actual unflattening */ + start = ((unsigned long)initial_boot_params) + + initial_boot_params->off_dt_struct; + unflatten_dt_node(mem, &start, NULL, &allnextp, 0); + if (*((u32 *)start) != OF_DT_END) + printk(KERN_WARNING "Weird tag at end of tree: %08x\n", + *((u32 *)start)); + if (((u32 *)mem)[size / 4] != 0xdeadbeef) + printk(KERN_WARNING "End of tree marker overwritten: %08x\n", + ((u32 *)mem)[size / 4]); + *allnextp = NULL; + + /* Get pointer to OF "/chosen" node for use everywhere */ + of_chosen = of_find_node_by_path("/chosen"); + if (of_chosen == NULL) + of_chosen = of_find_node_by_path("/chosen@0"); + + pr_debug(" <- unflatten_device_tree()\n"); +} + +#define early_init_dt_scan_drconf_memory(node) 0 + +static int __init early_init_dt_scan_cpus(unsigned long node, + const char *uname, int depth, + void *data) +{ + static int logical_cpuid; + char *type = of_get_flat_dt_prop(node, "device_type", NULL); + const u32 *intserv; + int i, nthreads; + int found = 0; + + /* We are scanning "cpu" nodes only */ + if (type == NULL || strcmp(type, "cpu") != 0) + return 0; + + /* Get physical cpuid */ + intserv = of_get_flat_dt_prop(node, "reg", NULL); + nthreads = 1; + + /* + * Now see if any of these threads match our boot cpu. + * NOTE: This must match the parsing done in smp_setup_cpu_maps. + */ + for (i = 0; i < nthreads; i++) { + /* + * version 2 of the kexec param format adds the phys cpuid of + * booted proc. + */ + if (initial_boot_params && initial_boot_params->version >= 2) { + if (intserv[i] == + initial_boot_params->boot_cpuid_phys) { + found = 1; + break; + } + } else { + /* + * Check if it's the boot-cpu, set it's hw index now, + * unfortunately this format did not support booting + * off secondary threads. + */ + if (of_get_flat_dt_prop(node, + "linux,boot-cpu", NULL) != NULL) { + found = 1; + break; + } + } + +#ifdef CONFIG_SMP + /* logical cpu id is always 0 on UP kernels */ + logical_cpuid++; +#endif + } + + if (found) { + pr_debug("boot cpu: logical %d physical %d\n", logical_cpuid, + intserv[i]); + boot_cpuid = logical_cpuid; + } + + return 0; +} + +#ifdef CONFIG_BLK_DEV_INITRD +static void __init early_init_dt_check_for_initrd(unsigned long node) +{ + unsigned long l; + u32 *prop; + + pr_debug("Looking for initrd properties... "); + + prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l); + if (prop) { + initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4)); + + prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l); + if (prop) { + initrd_end = (unsigned long) + __va(of_read_ulong(prop, l/4)); + initrd_below_start_ok = 1; + } else { + initrd_start = 0; + } + } + + pr_debug("initrd_start=0x%lx initrd_end=0x%lx\n", + initrd_start, initrd_end); +} +#else +static inline void early_init_dt_check_for_initrd(unsigned long node) +{ +} +#endif /* CONFIG_BLK_DEV_INITRD */ + +static int __init early_init_dt_scan_chosen(unsigned long node, + const char *uname, int depth, void *data) +{ + unsigned long l; + char *p; + + pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); + + if (depth != 1 || + (strcmp(uname, "chosen") != 0 && + strcmp(uname, "chosen@0") != 0)) + return 0; + +#ifdef CONFIG_KEXEC + lprop = (u64 *)of_get_flat_dt_prop(node, + "linux,crashkernel-base", NULL); + if (lprop) + crashk_res.start = *lprop; + + lprop = (u64 *)of_get_flat_dt_prop(node, + "linux,crashkernel-size", NULL); + if (lprop) + crashk_res.end = crashk_res.start + *lprop - 1; +#endif + + early_init_dt_check_for_initrd(node); + + /* Retreive command line */ + p = of_get_flat_dt_prop(node, "bootargs", &l); + if (p != NULL && l > 0) + strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE)); + +#ifdef CONFIG_CMDLINE + if (p == NULL || l == 0 || (l == 1 && (*p) == 0)) + strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); +#endif /* CONFIG_CMDLINE */ + + pr_debug("Command line is: %s\n", cmd_line); + + /* break now */ + return 1; +} + +static int __init early_init_dt_scan_root(unsigned long node, + const char *uname, int depth, void *data) +{ + u32 *prop; + + if (depth != 0) + return 0; + + prop = of_get_flat_dt_prop(node, "#size-cells", NULL); + dt_root_size_cells = (prop == NULL) ? 1 : *prop; + pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells); + + prop = of_get_flat_dt_prop(node, "#address-cells", NULL); + dt_root_addr_cells = (prop == NULL) ? 2 : *prop; + pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells); + + /* break now */ + return 1; +} + +static u64 __init dt_mem_next_cell(int s, cell_t **cellp) +{ + cell_t *p = *cellp; + + *cellp = p + s; + return of_read_number(p, s); +} + +static int __init early_init_dt_scan_memory(unsigned long node, + const char *uname, int depth, void *data) +{ + char *type = of_get_flat_dt_prop(node, "device_type", NULL); + cell_t *reg, *endp; + unsigned long l; + + /* Look for the ibm,dynamic-reconfiguration-memory node */ +/* if (depth == 1 && + strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) + return early_init_dt_scan_drconf_memory(node); +*/ + /* We are scanning "memory" nodes only */ + if (type == NULL) { + /* + * The longtrail doesn't have a device_type on the + * /memory node, so look for the node called /memory@0. + */ + if (depth != 1 || strcmp(uname, "memory@0") != 0) + return 0; + } else if (strcmp(type, "memory") != 0) + return 0; + + reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l); + if (reg == NULL) + reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); + if (reg == NULL) + return 0; + + endp = reg + (l / sizeof(cell_t)); + + pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n", + uname, l, reg[0], reg[1], reg[2], reg[3]); + + while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { + u64 base, size; + + base = dt_mem_next_cell(dt_root_addr_cells, ®); + size = dt_mem_next_cell(dt_root_size_cells, ®); + + if (size == 0) + continue; + pr_debug(" - %llx , %llx\n", (unsigned long long)base, + (unsigned long long)size); + + lmb_add(base, size); + } + return 0; +} + +#ifdef CONFIG_PHYP_DUMP +/** + * phyp_dump_calculate_reserve_size() - reserve variable boot area 5% or arg + * + * Function to find the largest size we need to reserve + * during early boot process. + * + * It either looks for boot param and returns that OR + * returns larger of 256 or 5% rounded down to multiples of 256MB. + * + */ +static inline unsigned long phyp_dump_calculate_reserve_size(void) +{ + unsigned long tmp; + + if (phyp_dump_info->reserve_bootvar) + return phyp_dump_info->reserve_bootvar; + + /* divide by 20 to get 5% of value */ + tmp = lmb_end_of_DRAM(); + do_div(tmp, 20); + + /* round it down in multiples of 256 */ + tmp = tmp & ~0x0FFFFFFFUL; + + return (tmp > PHYP_DUMP_RMR_END ? tmp : PHYP_DUMP_RMR_END); +} + +/** + * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory + * + * This routine may reserve memory regions in the kernel only + * if the system is supported and a dump was taken in last + * boot instance or if the hardware is supported and the + * scratch area needs to be setup. In other instances it returns + * without reserving anything. The memory in case of dump being + * active is freed when the dump is collected (by userland tools). + */ +static void __init phyp_dump_reserve_mem(void) +{ + unsigned long base, size; + unsigned long variable_reserve_size; + + if (!phyp_dump_info->phyp_dump_configured) { + printk(KERN_ERR "Phyp-dump not supported on this hardware\n"); + return; + } + + if (!phyp_dump_info->phyp_dump_at_boot) { + printk(KERN_INFO "Phyp-dump disabled at boot time\n"); + return; + } + + variable_reserve_size = phyp_dump_calculate_reserve_size(); + + if (phyp_dump_info->phyp_dump_is_active) { + /* Reserve *everything* above RMR.Area freed by userland tools*/ + base = variable_reserve_size; + size = lmb_end_of_DRAM() - base; + + /* XXX crashed_ram_end is wrong, since it may be beyond + * the memory_limit, it will need to be adjusted. */ + lmb_reserve(base, size); + + phyp_dump_info->init_reserve_start = base; + phyp_dump_info->init_reserve_size = size; + } else { + size = phyp_dump_info->cpu_state_size + + phyp_dump_info->hpte_region_size + + variable_reserve_size; + base = lmb_end_of_DRAM() - size; + lmb_reserve(base, size); + phyp_dump_info->init_reserve_start = base; + phyp_dump_info->init_reserve_size = size; + } +} +#else +static inline void __init phyp_dump_reserve_mem(void) {} +#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */ + +#ifdef CONFIG_EARLY_PRINTK +/* MS this is Microblaze specifig function */ +static int __init early_init_dt_scan_serial(unsigned long node, + const char *uname, int depth, void *data) +{ + unsigned long l; + char *p; + int *addr; + + pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); + +/* find all serial nodes */ + if (strncmp(uname, "serial", 6) != 0) + return 0; + + early_init_dt_check_for_initrd(node); + +/* find compatible node with uartlite */ + p = of_get_flat_dt_prop(node, "compatible", &l); + if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && + (strncmp(p, "xlnx,opb-uartlite", 17) != 0)) + return 0; + + addr = of_get_flat_dt_prop(node, "reg", &l); + return *addr; /* return address */ +} + +/* this function is looking for early uartlite console - Microblaze specific */ +int __init early_uartlite_console(void) +{ + return of_scan_flat_dt(early_init_dt_scan_serial, NULL); +} +#endif + +void __init early_init_devtree(void *params) +{ + pr_debug(" -> early_init_devtree(%p)\n", params); + + /* Setup flat device-tree pointer */ + initial_boot_params = params; + +#ifdef CONFIG_PHYP_DUMP + /* scan tree to see if dump occured during last boot */ + of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL); +#endif + + /* Retrieve various informations from the /chosen node of the + * device-tree, including the platform type, initrd location and + * size, TCE reserve, and more ... + */ + of_scan_flat_dt(early_init_dt_scan_chosen, NULL); + + /* Scan memory nodes and rebuild LMBs */ + lmb_init(); + of_scan_flat_dt(early_init_dt_scan_root, NULL); + of_scan_flat_dt(early_init_dt_scan_memory, NULL); + + /* Save command line for /proc/cmdline and then parse parameters */ + strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); + parse_early_param(); + + lmb_analyze(); + + pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size()); + + pr_debug("Scanning CPUs ...\n"); + + /* Retreive CPU related informations from the flat tree + * (altivec support, boot CPU ID, ...) + */ + of_scan_flat_dt(early_init_dt_scan_cpus, NULL); + + pr_debug(" <- early_init_devtree()\n"); +} + +/** + * Indicates whether the root node has a given value in its + * compatible property. + */ +int machine_is_compatible(const char *compat) +{ + struct device_node *root; + int rc = 0; + + root = of_find_node_by_path("/"); + if (root) { + rc = of_device_is_compatible(root, compat); + of_node_put(root); + } + return rc; +} +EXPORT_SYMBOL(machine_is_compatible); + +/******* + * + * New implementation of the OF "find" APIs, return a refcounted + * object, call of_node_put() when done. The device tree and list + * are protected by a rw_lock. + * + * Note that property management will need some locking as well, + * this isn't dealt with yet. + * + *******/ + +/** + * of_find_node_by_phandle - Find a node given a phandle + * @handle: phandle of the node to find + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_phandle(phandle handle) +{ + struct device_node *np; + + read_lock(&devtree_lock); + for (np = allnodes; np != NULL; np = np->allnext) + if (np->linux_phandle == handle) + break; + of_node_get(np); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_node_by_phandle); + +/** + * of_find_all_nodes - Get next node in global list + * @prev: Previous node or NULL to start iteration + * of_node_put() will be called on it + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_all_nodes(struct device_node *prev) +{ + struct device_node *np; + + read_lock(&devtree_lock); + np = prev ? prev->allnext : allnodes; + for (; np != NULL; np = np->allnext) + if (of_node_get(np)) + break; + of_node_put(prev); + read_unlock(&devtree_lock); + return np; +} +EXPORT_SYMBOL(of_find_all_nodes); + +/** + * of_node_get - Increment refcount of a node + * @node: Node to inc refcount, NULL is supported to + * simplify writing of callers + * + * Returns node. + */ +struct device_node *of_node_get(struct device_node *node) +{ + if (node) + kref_get(&node->kref); + return node; +} +EXPORT_SYMBOL(of_node_get); + +static inline struct device_node *kref_to_device_node(struct kref *kref) +{ + return container_of(kref, struct device_node, kref); +} + +/** + * of_node_release - release a dynamically allocated node + * @kref: kref element of the node to be released + * + * In of_node_put() this function is passed to kref_put() + * as the destructor. + */ +static void of_node_release(struct kref *kref) +{ + struct device_node *node = kref_to_device_node(kref); + struct property *prop = node->properties; + + /* We should never be releasing nodes that haven't been detached. */ + if (!of_node_check_flag(node, OF_DETACHED)) { + printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n", + node->full_name); + dump_stack(); + kref_init(&node->kref); + return; + } + + if (!of_node_check_flag(node, OF_DYNAMIC)) + return; + + while (prop) { + struct property *next = prop->next; + kfree(prop->name); + kfree(prop->value); + kfree(prop); + prop = next; + + if (!prop) { + prop = node->deadprops; + node->deadprops = NULL; + } + } + kfree(node->full_name); + kfree(node->data); + kfree(node); +} + +/** + * of_node_put - Decrement refcount of a node + * @node: Node to dec refcount, NULL is supported to + * simplify writing of callers + * + */ +void of_node_put(struct device_node *node) +{ + if (node) + kref_put(&node->kref, of_node_release); +} +EXPORT_SYMBOL(of_node_put); + +/* + * Plug a device node into the tree and global list. + */ +void of_attach_node(struct device_node *np) +{ + unsigned long flags; + + write_lock_irqsave(&devtree_lock, flags); + np->sibling = np->parent->child; + np->allnext = allnodes; + np->parent->child = np; + allnodes = np; + write_unlock_irqrestore(&devtree_lock, flags); +} + +/* + * "Unplug" a node from the device tree. The caller must hold + * a reference to the node. The memory associated with the node + * is not freed until its refcount goes to zero. + */ +void of_detach_node(struct device_node *np) +{ + struct device_node *parent; + unsigned long flags; + + write_lock_irqsave(&devtree_lock, flags); + + parent = np->parent; + if (!parent) + goto out_unlock; + + if (allnodes == np) + allnodes = np->allnext; + else { + struct device_node *prev; + for (prev = allnodes; + prev->allnext != np; + prev = prev->allnext) + ; + prev->allnext = np->allnext; + } + + if (parent->child == np) + parent->child = np->sibling; + else { + struct device_node *prevsib; + for (prevsib = np->parent->child; + prevsib->sibling != np; + prevsib = prevsib->sibling) + ; + prevsib->sibling = np->sibling; + } + + of_node_set_flag(np, OF_DETACHED); + +out_unlock: + write_unlock_irqrestore(&devtree_lock, flags); +} + +/* + * Add a property to a node + */ +int prom_add_property(struct device_node *np, struct property *prop) +{ + struct property **next; + unsigned long flags; + + prop->next = NULL; + write_lock_irqsave(&devtree_lock, flags); + next = &np->properties; + while (*next) { + if (strcmp(prop->name, (*next)->name) == 0) { + /* duplicate ! don't insert it */ + write_unlock_irqrestore(&devtree_lock, flags); + return -1; + } + next = &(*next)->next; + } + *next = prop; + write_unlock_irqrestore(&devtree_lock, flags); + +#ifdef CONFIG_PROC_DEVICETREE + /* try to add to proc as well if it was initialized */ + if (np->pde) + proc_device_tree_add_prop(np->pde, prop); +#endif /* CONFIG_PROC_DEVICETREE */ + + return 0; +} + +/* + * Remove a property from a node. Note that we don't actually + * remove it, since we have given out who-knows-how-many pointers + * to the data using get-property. Instead we just move the property + * to the "dead properties" list, so it won't be found any more. + */ +int prom_remove_property(struct device_node *np, struct property *prop) +{ + struct property **next; + unsigned long flags; + int found = 0; + + write_lock_irqsave(&devtree_lock, flags); + next = &np->properties; + while (*next) { + if (*next == prop) { + /* found the node */ + *next = prop->next; + prop->next = np->deadprops; + np->deadprops = prop; + found = 1; + break; + } + next = &(*next)->next; + } + write_unlock_irqrestore(&devtree_lock, flags); + + if (!found) + return -ENODEV; + +#ifdef CONFIG_PROC_DEVICETREE + /* try to remove the proc node as well */ + if (np->pde) + proc_device_tree_remove_prop(np->pde, prop); +#endif /* CONFIG_PROC_DEVICETREE */ + + return 0; +} + +/* + * Update a property in a node. Note that we don't actually + * remove it, since we have given out who-knows-how-many pointers + * to the data using get-property. Instead we just move the property + * to the "dead properties" list, and add the new property to the + * property list + */ +int prom_update_property(struct device_node *np, + struct property *newprop, + struct property *oldprop) +{ + struct property **next; + unsigned long flags; + int found = 0; + + write_lock_irqsave(&devtree_lock, flags); + next = &np->properties; + while (*next) { + if (*next == oldprop) { + /* found the node */ + newprop->next = oldprop->next; + *next = newprop; + oldprop->next = np->deadprops; + np->deadprops = oldprop; + found = 1; + break; + } + next = &(*next)->next; + } + write_unlock_irqrestore(&devtree_lock, flags); + + if (!found) + return -ENODEV; + +#ifdef CONFIG_PROC_DEVICETREE + /* try to add to proc as well if it was initialized */ + if (np->pde) + proc_device_tree_update_prop(np->pde, newprop, oldprop); +#endif /* CONFIG_PROC_DEVICETREE */ + + return 0; +} + +#if defined(CONFIG_DEBUG_FS) && defined(DEBUG) +static struct debugfs_blob_wrapper flat_dt_blob; + +static int __init export_flat_device_tree(void) +{ + struct dentry *d; + + flat_dt_blob.data = initial_boot_params; + flat_dt_blob.size = initial_boot_params->totalsize; + + d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, + of_debugfs_root, &flat_dt_blob); + if (!d) + return 1; + + return 0; +} +device_initcall(export_flat_device_tree); +#endif diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c new file mode 100644 index 0000000..ae0352e --- /dev/null +++ b/arch/microblaze/kernel/prom_parse.c @@ -0,0 +1,1025 @@ +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/pci_regs.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/etherdevice.h> +#include <asm/prom.h> +#include <asm/pci-bridge.h> + +#define PRu64 "%llx" + +/* Max address size we deal with */ +#define OF_MAX_ADDR_CELLS 4 +#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ + (ns) > 0) + +static struct of_bus *of_match_bus(struct device_node *np); +static int __of_address_to_resource(struct device_node *dev, + const u32 *addrp, u64 size, unsigned int flags, + struct resource *r); + +/* Debug utility */ +#ifdef DEBUG +static void of_dump_addr(const char *s, const u32 *addr, int na) +{ + printk(KERN_INFO "%s", s); + while (na--) + printk(KERN_INFO " %08x", *(addr++)); + printk(KERN_INFO "\n"); +} +#else +static void of_dump_addr(const char *s, const u32 *addr, int na) { } +#endif + +/* Callbacks for bus specific translators */ +struct of_bus { + const char *name; + const char *addresses; + int (*match)(struct device_node *parent); + void (*count_cells)(struct device_node *child, + int *addrc, int *sizec); + u64 (*map)(u32 *addr, const u32 *range, + int na, int ns, int pna); + int (*translate)(u32 *addr, u64 offset, int na); + unsigned int (*get_flags)(const u32 *addr); +}; + +/* + * Default translator (generic bus) + */ + +static void of_bus_default_count_cells(struct device_node *dev, + int *addrc, int *sizec) +{ + if (addrc) + *addrc = of_n_addr_cells(dev); + if (sizec) + *sizec = of_n_size_cells(dev); +} + +static u64 of_bus_default_map(u32 *addr, const u32 *range, + int na, int ns, int pna) +{ + u64 cp, s, da; + + cp = of_read_number(range, na); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr, na); + + pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", + cp, s, da); + + if (da < cp || da >= (cp + s)) + return OF_BAD_ADDR; + return da - cp; +} + +static int of_bus_default_translate(u32 *addr, u64 offset, int na) +{ + u64 a = of_read_number(addr, na); + memset(addr, 0, na * 4); + a += offset; + if (na > 1) + addr[na - 2] = a >> 32; + addr[na - 1] = a & 0xffffffffu; + + return 0; +} + +static unsigned int of_bus_default_get_flags(const u32 *addr) +{ + return IORESOURCE_MEM; +} + +#ifdef CONFIG_PCI +/* + * PCI bus specific translator + */ + +static int of_bus_pci_match(struct device_node *np) +{ + /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ + return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); +} + +static void of_bus_pci_count_cells(struct device_node *np, + int *addrc, int *sizec) +{ + if (addrc) + *addrc = 3; + if (sizec) + *sizec = 2; +} + +static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) +{ + u64 cp, s, da; + + /* Check address type match */ + if ((addr[0] ^ range[0]) & 0x03000000) + return OF_BAD_ADDR; + + /* Read address values, skipping high cell */ + cp = of_read_number(range + 1, na - 1); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr + 1, na - 1); + + pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); + + if (da < cp || da >= (cp + s)) + return OF_BAD_ADDR; + return da - cp; +} + +static int of_bus_pci_translate(u32 *addr, u64 offset, int na) +{ + return of_bus_default_translate(addr + 1, offset, na - 1); +} + +static unsigned int of_bus_pci_get_flags(const u32 *addr) +{ + unsigned int flags = 0; + u32 w = addr[0]; + + switch ((w >> 24) & 0x03) { + case 0x01: + flags |= IORESOURCE_IO; + break; + case 0x02: /* 32 bits */ + case 0x03: /* 64 bits */ + flags |= IORESOURCE_MEM; + break; + } + if (w & 0x40000000) + flags |= IORESOURCE_PREFETCH; + return flags; +} + +const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, + unsigned int *flags) +{ + const u32 *prop; + unsigned int psize; + struct device_node *parent; + struct of_bus *bus; + int onesize, i, na, ns; + + /* Get parent & match bus type */ + parent = of_get_parent(dev); + if (parent == NULL) + return NULL; + bus = of_match_bus(parent); + if (strcmp(bus->name, "pci")) { + of_node_put(parent); + return NULL; + } + bus->count_cells(dev, &na, &ns); + of_node_put(parent); + if (!OF_CHECK_COUNTS(na, ns)) + return NULL; + + /* Get "reg" or "assigned-addresses" property */ + prop = of_get_property(dev, bus->addresses, &psize); + if (prop == NULL) + return NULL; + psize /= 4; + + onesize = na + ns; + for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) + if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { + if (size) + *size = of_read_number(prop + na, ns); + if (flags) + *flags = bus->get_flags(prop); + return prop; + } + return NULL; +} +EXPORT_SYMBOL(of_get_pci_address); + +int of_pci_address_to_resource(struct device_node *dev, int bar, + struct resource *r) +{ + const u32 *addrp; + u64 size; + unsigned int flags; + + addrp = of_get_pci_address(dev, bar, &size, &flags); + if (addrp == NULL) + return -EINVAL; + return __of_address_to_resource(dev, addrp, size, flags, r); +} +EXPORT_SYMBOL_GPL(of_pci_address_to_resource); + +static u8 of_irq_pci_swizzle(u8 slot, u8 pin) +{ + return (((pin - 1) + slot) % 4) + 1; +} + +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) +{ + struct device_node *dn, *ppnode; + struct pci_dev *ppdev; + u32 lspec; + u32 laddr[3]; + u8 pin; + int rc; + + /* Check if we have a device node, if yes, fallback to standard OF + * parsing + */ + dn = pci_device_to_OF_node(pdev); + if (dn) + return of_irq_map_one(dn, 0, out_irq); + + /* Ok, we don't, time to have fun. Let's start by building up an + * interrupt spec. we assume #interrupt-cells is 1, which is standard + * for PCI. If you do different, then don't use that routine. + */ + rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); + if (rc != 0) + return rc; + /* No pin, exit */ + if (pin == 0) + return -ENODEV; + + /* Now we walk up the PCI tree */ + lspec = pin; + for (;;) { + /* Get the pci_dev of our parent */ + ppdev = pdev->bus->self; + + /* Ouch, it's a host bridge... */ + if (ppdev == NULL) { + struct pci_controller *host; + host = pci_bus_to_host(pdev->bus); + ppnode = host ? host->arch_data : NULL; + /* No node for host bridge ? give up */ + if (ppnode == NULL) + return -EINVAL; + } else + /* We found a P2P bridge, check if it has a node */ + ppnode = pci_device_to_OF_node(ppdev); + + /* Ok, we have found a parent with a device-node, hand over to + * the OF parsing code. + * We build a unit address from the linux device to be used for + * resolution. Note that we use the linux bus number which may + * not match your firmware bus numbering. + * Fortunately, in most cases, interrupt-map-mask doesn't + * include the bus number as part of the matching. + * You should still be careful about that though if you intend + * to rely on this function (you ship a firmware that doesn't + * create device nodes for all PCI devices). + */ + if (ppnode) + break; + + /* We can only get here if we hit a P2P bridge with no node, + * let's do standard swizzling and try again + */ + lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec); + pdev = ppdev; + } + + laddr[0] = (pdev->bus->number << 16) + | (pdev->devfn << 8); + laddr[1] = laddr[2] = 0; + return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); +} +EXPORT_SYMBOL_GPL(of_irq_map_pci); +#endif /* CONFIG_PCI */ + +/* + * ISA bus specific translator + */ + +static int of_bus_isa_match(struct device_node *np) +{ + return !strcmp(np->name, "isa"); +} + +static void of_bus_isa_count_cells(struct device_node *child, + int *addrc, int *sizec) +{ + if (addrc) + *addrc = 2; + if (sizec) + *sizec = 1; +} + +static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) +{ + u64 cp, s, da; + + /* Check address type match */ + if ((addr[0] ^ range[0]) & 0x00000001) + return OF_BAD_ADDR; + + /* Read address values, skipping high cell */ + cp = of_read_number(range + 1, na - 1); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr + 1, na - 1); + + pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); + + if (da < cp || da >= (cp + s)) + return OF_BAD_ADDR; + return da - cp; +} + +static int of_bus_isa_translate(u32 *addr, u64 offset, int na) +{ + return of_bus_default_translate(addr + 1, offset, na - 1); +} + +static unsigned int of_bus_isa_get_flags(const u32 *addr) +{ + unsigned int flags = 0; + u32 w = addr[0]; + + if (w & 1) + flags |= IORESOURCE_IO; + else + flags |= IORESOURCE_MEM; + return flags; +} + +/* + * Array of bus specific translators + */ + +static struct of_bus of_busses[] = { +#ifdef CONFIG_PCI + /* PCI */ + { + .name = "pci", + .addresses = "assigned-addresses", + .match = of_bus_pci_match, + .count_cells = of_bus_pci_count_cells, + .map = of_bus_pci_map, + .translate = of_bus_pci_translate, + .get_flags = of_bus_pci_get_flags, + }, +#endif /* CONFIG_PCI */ + /* ISA */ + { + .name = "isa", + .addresses = "reg", + .match = of_bus_isa_match, + .count_cells = of_bus_isa_count_cells, + .map = of_bus_isa_map, + .translate = of_bus_isa_translate, + .get_flags = of_bus_isa_get_flags, + }, + /* Default */ + { + .name = "default", + .addresses = "reg", + .match = NULL, + .count_cells = of_bus_default_count_cells, + .map = of_bus_default_map, + .translate = of_bus_default_translate, + .get_flags = of_bus_default_get_flags, + }, +}; + +static struct of_bus *of_match_bus(struct device_node *np) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(of_busses); i++) + if (!of_busses[i].match || of_busses[i].match(np)) + return &of_busses[i]; + BUG(); + return NULL; +} + +static int of_translate_one(struct device_node *parent, struct of_bus *bus, + struct of_bus *pbus, u32 *addr, + int na, int ns, int pna) +{ + const u32 *ranges; + unsigned int rlen; + int rone; + u64 offset = OF_BAD_ADDR; + + /* Normally, an absence of a "ranges" property means we are + * crossing a non-translatable boundary, and thus the addresses + * below the current not cannot be converted to CPU physical ones. + * Unfortunately, while this is very clear in the spec, it's not + * what Apple understood, and they do have things like /uni-n or + * /ht nodes with no "ranges" property and a lot of perfectly + * useable mapped devices below them. Thus we treat the absence of + * "ranges" as equivalent to an empty "ranges" property which means + * a 1:1 translation at that level. It's up to the caller not to try + * to translate addresses that aren't supposed to be translated in + * the first place. --BenH. + */ + ranges = of_get_property(parent, "ranges", (int *) &rlen); + if (ranges == NULL || rlen == 0) { + offset = of_read_number(addr, na); + memset(addr, 0, pna * 4); + pr_debug("OF: no ranges, 1:1 translation\n"); + goto finish; + } + + pr_debug("OF: walking ranges...\n"); + + /* Now walk through the ranges */ + rlen /= 4; + rone = na + pna + ns; + for (; rlen >= rone; rlen -= rone, ranges += rone) { + offset = bus->map(addr, ranges, na, ns, pna); + if (offset != OF_BAD_ADDR) + break; + } + if (offset == OF_BAD_ADDR) { + pr_debug("OF: not found !\n"); + return 1; + } + memcpy(addr, ranges + na, 4 * pna); + + finish: + of_dump_addr("OF: parent translation for:", addr, pna); + pr_debug("OF: with offset: "PRu64"\n", offset); + + /* Translate it into parent bus space */ + return pbus->translate(addr, offset, pna); +} + +/* + * Translate an address from the device-tree into a CPU physical address, + * this walks up the tree and applies the various bus mappings on the + * way. + * + * Note: We consider that crossing any level with #size-cells == 0 to mean + * that translation is impossible (that is we are not dealing with a value + * that can be mapped to a cpu physical address). This is not really specified + * that way, but this is traditionally the way IBM at least do things + */ +u64 of_translate_address(struct device_node *dev, const u32 *in_addr) +{ + struct device_node *parent = NULL; + struct of_bus *bus, *pbus; + u32 addr[OF_MAX_ADDR_CELLS]; + int na, ns, pna, pns; + u64 result = OF_BAD_ADDR; + + pr_debug("OF: ** translation for device %s **\n", dev->full_name); + + /* Increase refcount at current level */ + of_node_get(dev); + + /* Get parent & match bus type */ + parent = of_get_parent(dev); + if (parent == NULL) + goto bail; + bus = of_match_bus(parent); + + /* Cound address cells & copy address locally */ + bus->count_cells(dev, &na, &ns); + if (!OF_CHECK_COUNTS(na, ns)) { + printk(KERN_ERR "prom_parse: Bad cell count for %s\n", + dev->full_name); + goto bail; + } + memcpy(addr, in_addr, na * 4); + + pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", + bus->name, na, ns, parent->full_name); + of_dump_addr("OF: translating address:", addr, na); + + /* Translate */ + for (;;) { + /* Switch to parent bus */ + of_node_put(dev); + dev = parent; + parent = of_get_parent(dev); + + /* If root, we have finished */ + if (parent == NULL) { + pr_debug("OF: reached root node\n"); + result = of_read_number(addr, na); + break; + } + + /* Get new parent bus and counts */ + pbus = of_match_bus(parent); + pbus->count_cells(dev, &pna, &pns); + if (!OF_CHECK_COUNTS(pna, pns)) { + printk(KERN_ERR "prom_parse: Bad cell count for %s\n", + dev->full_name); + break; + } + + pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", + pbus->name, pna, pns, parent->full_name); + + /* Apply bus translation */ + if (of_translate_one(dev, bus, pbus, addr, na, ns, pna)) + break; + + /* Complete the move up one level */ + na = pna; + ns = pns; + bus = pbus; + + of_dump_addr("OF: one level translation:", addr, na); + } + bail: + of_node_put(parent); + of_node_put(dev); + + return result; +} +EXPORT_SYMBOL(of_translate_address); + +const u32 *of_get_address(struct device_node *dev, int index, u64 *size, + unsigned int *flags) +{ + const u32 *prop; + unsigned int psize; + struct device_node *parent; + struct of_bus *bus; + int onesize, i, na, ns; + + /* Get parent & match bus type */ + parent = of_get_parent(dev); + if (parent == NULL) + return NULL; + bus = of_match_bus(parent); + bus->count_cells(dev, &na, &ns); + of_node_put(parent); + if (!OF_CHECK_COUNTS(na, ns)) + return NULL; + + /* Get "reg" or "assigned-addresses" property */ + prop = of_get_property(dev, bus->addresses, (int *) &psize); + if (prop == NULL) + return NULL; + psize /= 4; + + onesize = na + ns; + for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) + if (i == index) { + if (size) + *size = of_read_number(prop + na, ns); + if (flags) + *flags = bus->get_flags(prop); + return prop; + } + return NULL; +} +EXPORT_SYMBOL(of_get_address); + +static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, + u64 size, unsigned int flags, + struct resource *r) +{ + u64 taddr; + + if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) + return -EINVAL; + taddr = of_translate_address(dev, addrp); + if (taddr == OF_BAD_ADDR) + return -EINVAL; + memset(r, 0, sizeof(struct resource)); + if (flags & IORESOURCE_IO) { + unsigned long port; + port = -1; /* pci_address_to_pio(taddr); */ + if (port == (unsigned long)-1) + return -EINVAL; + r->start = port; + r->end = port + size - 1; + } else { + r->start = taddr; + r->end = taddr + size - 1; + } + r->flags = flags; + r->name = dev->name; + return 0; +} + +int of_address_to_resource(struct device_node *dev, int index, + struct resource *r) +{ + const u32 *addrp; + u64 size; + unsigned int flags; + + addrp = of_get_address(dev, index, &size, &flags); + if (addrp == NULL) + return -EINVAL; + return __of_address_to_resource(dev, addrp, size, flags, r); +} +EXPORT_SYMBOL_GPL(of_address_to_resource); + +void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, + unsigned long *busno, unsigned long *phys, unsigned long *size) +{ + const u32 *dma_window; + u32 cells; + const unsigned char *prop; + + dma_window = dma_window_prop; + + /* busno is always one cell */ + *busno = *(dma_window++); + + prop = of_get_property(dn, "ibm,#dma-address-cells", NULL); + if (!prop) + prop = of_get_property(dn, "#address-cells", NULL); + + cells = prop ? *(u32 *)prop : of_n_addr_cells(dn); + *phys = of_read_number(dma_window, cells); + + dma_window += cells; + + prop = of_get_property(dn, "ibm,#dma-size-cells", NULL); + cells = prop ? *(u32 *)prop : of_n_size_cells(dn); + *size = of_read_number(dma_window, cells); +} + +/* + * Interrupt remapper + */ + +static unsigned int of_irq_workarounds; +static struct device_node *of_irq_dflt_pic; + +static struct device_node *of_irq_find_parent(struct device_node *child) +{ + struct device_node *p; + const phandle *parp; + + if (!of_node_get(child)) + return NULL; + + do { + parp = of_get_property(child, "interrupt-parent", NULL); + if (parp == NULL) + p = of_get_parent(child); + else { + if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) + p = of_node_get(of_irq_dflt_pic); + else + p = of_find_node_by_phandle(*parp); + } + of_node_put(child); + child = p; + } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); + + return p; +} + +/* This doesn't need to be called if you don't have any special workaround + * flags to pass + */ +void of_irq_map_init(unsigned int flags) +{ + of_irq_workarounds = flags; + + /* OldWorld, don't bother looking at other things */ + if (flags & OF_IMAP_OLDWORLD_MAC) + return; + + /* If we don't have phandles, let's try to locate a default interrupt + * controller (happens when booting with BootX). We do a first match + * here, hopefully, that only ever happens on machines with one + * controller. + */ + if (flags & OF_IMAP_NO_PHANDLE) { + struct device_node *np; + + for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) { + if (of_get_property(np, "interrupt-controller", NULL) + == NULL) + continue; + /* Skip /chosen/interrupt-controller */ + if (strcmp(np->name, "chosen") == 0) + continue; + /* It seems like at least one person on this planet + * wants to use BootX on a machine with an AppleKiwi + * controller which happens to pretend to be an + * interrupt controller too. + */ + if (strcmp(np->name, "AppleKiwi") == 0) + continue; + /* I think we found one ! */ + of_irq_dflt_pic = np; + break; + } + } + +} + +int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, + const u32 *addr, struct of_irq *out_irq) +{ + struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; + const u32 *tmp, *imap, *imask; + u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; + int imaplen, match, i; + + pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...]," + "ointsize=%d\n", + parent->full_name, intspec[0], intspec[1], ointsize); + + ipar = of_node_get(parent); + + /* First get the #interrupt-cells property of the current cursor + * that tells us how to interpret the passed-in intspec. If there + * is none, we are nice and just walk up the tree + */ + do { + tmp = of_get_property(ipar, "#interrupt-cells", NULL); + if (tmp != NULL) { + intsize = *tmp; + break; + } + tnode = ipar; + ipar = of_irq_find_parent(ipar); + of_node_put(tnode); + } while (ipar); + if (ipar == NULL) { + pr_debug(" -> no parent found !\n"); + goto fail; + } + + pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", + ipar->full_name, intsize); + + if (ointsize != intsize) + return -EINVAL; + + /* Look for this #address-cells. We have to implement the old linux + * trick of looking for the parent here as some device-trees rely on it + */ + old = of_node_get(ipar); + do { + tmp = of_get_property(old, "#address-cells", NULL); + tnode = of_get_parent(old); + of_node_put(old); + old = tnode; + } while (old && tmp == NULL); + of_node_put(old); + old = NULL; + addrsize = (tmp == NULL) ? 2 : *tmp; + + pr_debug(" -> addrsize=%d\n", addrsize); + + /* Now start the actual "proper" walk of the interrupt tree */ + while (ipar != NULL) { + /* Now check if cursor is an interrupt-controller and if it is + * then we are done + */ + if (of_get_property(ipar, "interrupt-controller", NULL) != + NULL) { + pr_debug(" -> got it !\n"); + memcpy(out_irq->specifier, intspec, + intsize * sizeof(u32)); + out_irq->size = intsize; + out_irq->controller = ipar; + of_node_put(old); + return 0; + } + + /* Now look for an interrupt-map */ + imap = of_get_property(ipar, "interrupt-map", &imaplen); + /* No interrupt map, check for an interrupt parent */ + if (imap == NULL) { + pr_debug(" -> no map, getting parent\n"); + newpar = of_irq_find_parent(ipar); + goto skiplevel; + } + imaplen /= sizeof(u32); + + /* Look for a mask */ + imask = of_get_property(ipar, "interrupt-map-mask", NULL); + + /* If we were passed no "reg" property and we attempt to parse + * an interrupt-map, then #address-cells must be 0. + * Fail if it's not. + */ + if (addr == NULL && addrsize != 0) { + pr_debug(" -> no reg passed in when needed !\n"); + goto fail; + } + + /* Parse interrupt-map */ + match = 0; + while (imaplen > (addrsize + intsize + 1) && !match) { + /* Compare specifiers */ + match = 1; + for (i = 0; i < addrsize && match; ++i) { + u32 mask = imask ? imask[i] : 0xffffffffu; + match = ((addr[i] ^ imap[i]) & mask) == 0; + } + for (; i < (addrsize + intsize) && match; ++i) { + u32 mask = imask ? imask[i] : 0xffffffffu; + match = + ((intspec[i-addrsize] ^ imap[i]) + & mask) == 0; + } + imap += addrsize + intsize; + imaplen -= addrsize + intsize; + + pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); + + /* Get the interrupt parent */ + if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) + newpar = of_node_get(of_irq_dflt_pic); + else + newpar = + of_find_node_by_phandle((phandle)*imap); + imap++; + --imaplen; + + /* Check if not found */ + if (newpar == NULL) { + pr_debug(" -> imap parent not found !\n"); + goto fail; + } + + /* Get #interrupt-cells and #address-cells of new + * parent + */ + tmp = of_get_property(newpar, "#interrupt-cells", NULL); + if (tmp == NULL) { + pr_debug(" -> parent lacks " + "#interrupt-cells!\n"); + goto fail; + } + newintsize = *tmp; + tmp = of_get_property(newpar, "#address-cells", NULL); + newaddrsize = (tmp == NULL) ? 0 : *tmp; + + pr_debug(" -> newintsize=%d, newaddrsize=%d\n", + newintsize, newaddrsize); + + /* Check for malformed properties */ + if (imaplen < (newaddrsize + newintsize)) + goto fail; + + imap += newaddrsize + newintsize; + imaplen -= newaddrsize + newintsize; + + pr_debug(" -> imaplen=%d\n", imaplen); + } + if (!match) + goto fail; + + of_node_put(old); + old = of_node_get(newpar); + addrsize = newaddrsize; + intsize = newintsize; + intspec = imap - intsize; + addr = intspec - addrsize; + +skiplevel: + /* Iterate again with new parent */ + pr_debug(" -> new parent: %s\n", + newpar ? newpar->full_name : "<>"); + of_node_put(ipar); + ipar = newpar; + newpar = NULL; + } +fail: + of_node_put(ipar); + of_node_put(old); + of_node_put(newpar); + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(of_irq_map_raw); + +int of_irq_map_one(struct device_node *device, + int index, struct of_irq *out_irq) +{ + struct device_node *p; + const u32 *intspec, *tmp, *addr; + u32 intsize, intlen; + int res; + + pr_debug("of_irq_map_one: dev=%s, index=%d\n", + device->full_name, index); + + /* Get the interrupts property */ + intspec = of_get_property(device, "interrupts", (int *) &intlen); + if (intspec == NULL) + return -EINVAL; + intlen /= sizeof(u32); + + pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen); + + /* Get the reg property (if any) */ + addr = of_get_property(device, "reg", NULL); + + /* Look for the interrupt parent. */ + p = of_irq_find_parent(device); + if (p == NULL) + return -EINVAL; + + /* Get size of interrupt specifier */ + tmp = of_get_property(p, "#interrupt-cells", NULL); + if (tmp == NULL) { + of_node_put(p); + return -EINVAL; + } + intsize = *tmp; + + pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); + + /* Check index */ + if ((index + 1) * intsize > intlen) + return -EINVAL; + + /* Get new specifier and map it */ + res = of_irq_map_raw(p, intspec + index * intsize, intsize, + addr, out_irq); + of_node_put(p); + return res; +} +EXPORT_SYMBOL_GPL(of_irq_map_one); + +/** + * Search the device tree for the best MAC address to use. 'mac-address' is + * checked first, because that is supposed to contain to "most recent" MAC + * address. If that isn't set, then 'local-mac-address' is checked next, + * because that is the default address. If that isn't set, then the obsolete + * 'address' is checked, just in case we're using an old device tree. + * + * Note that the 'address' property is supposed to contain a virtual address of + * the register set, but some DTS files have redefined that property to be the + * MAC address. + * + * All-zero MAC addresses are rejected, because those could be properties that + * exist in the device tree, but were not set by U-Boot. For example, the + * DTS could define 'mac-address' and 'local-mac-address', with zero MAC + * addresses. Some older U-Boots only initialized 'local-mac-address'. In + * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists + * but is all zeros. +*/ +const void *of_get_mac_address(struct device_node *np) +{ + struct property *pp; + + pp = of_find_property(np, "mac-address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + pp = of_find_property(np, "local-mac-address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + pp = of_find_property(np, "address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + return NULL; +} +EXPORT_SYMBOL(of_get_mac_address); + +int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) +{ + struct of_irq out_irq; + int irq; + int res; + + res = of_irq_map_one(dev, index, &out_irq); + + /* Get irq for the device */ + if (res) { + pr_debug("IRQ not found... code = %d", res); + return NO_IRQ; + } + /* Assuming single interrupt controller... */ + irq = out_irq.specifier[0]; + + pr_debug("IRQ found = %d", irq); + + /* Only dereference the resource if both the + * resource and the irq are valid. */ + if (r && irq != NO_IRQ) { + r->start = r->end = irq; + r->flags = IORESOURCE_IRQ; + } + + return irq; +} +EXPORT_SYMBOL_GPL(of_irq_to_resource); + +void __iomem *of_iomap(struct device_node *np, int index) +{ + struct resource res; + + if (of_address_to_resource(np, index, &res)) + return NULL; + + return ioremap(res.start, 1 + res.end - res.start); +} +EXPORT_SYMBOL(of_iomap); diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c new file mode 100644 index 0000000..b86aa62 --- /dev/null +++ b/arch/microblaze/kernel/ptrace.c @@ -0,0 +1,181 @@ +/* + * `ptrace' system call + * + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2004-2007 John Williams <john.williams@petalogix.com> + * + * derived from arch/v850/kernel/ptrace.c + * + * Copyright (C) 2002,03 NEC Electronics Corporation + * Copyright (C) 2002,03 Miles Bader <miles@gnu.org> + * + * Derived from arch/mips/kernel/ptrace.c: + * + * Copyright (C) 1992 Ross Biro + * Copyright (C) Linus Torvalds + * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle + * Copyright (C) 1996 David S. Miller + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999 MIPS Technologies, Inc. + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/smp_lock.h> +#include <linux/ptrace.h> +#include <linux/signal.h> + +#include <linux/errno.h> +#include <asm/processor.h> +#include <linux/uaccess.h> +#include <asm/asm-offsets.h> + +/* Returns the address where the register at REG_OFFS in P is stashed away. */ +static microblaze_reg_t *reg_save_addr(unsigned reg_offs, + struct task_struct *t) +{ + struct pt_regs *regs; + + /* + * Three basic cases: + * + * (1) A register normally saved before calling the scheduler, is + * available in the kernel entry pt_regs structure at the top + * of the kernel stack. The kernel trap/irq exit path takes + * care to save/restore almost all registers for ptrace'd + * processes. + * + * (2) A call-clobbered register, where the process P entered the + * kernel via [syscall] trap, is not stored anywhere; that's + * OK, because such registers are not expected to be preserved + * when the trap returns anyway (so we don't actually bother to + * test for this case). + * + * (3) A few registers not used at all by the kernel, and so + * normally never saved except by context-switches, are in the + * context switch state. + */ + + /* Register saved during kernel entry (or not available). */ + regs = task_pt_regs(t); + + return (microblaze_reg_t *)((char *)regs + reg_offs); +} + +long arch_ptrace(struct task_struct *child, long request, long addr, long data) +{ + int rval; + unsigned long val = 0; + unsigned long copied; + + switch (request) { + case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKDATA: + pr_debug("PEEKTEXT/PEEKDATA at %08lX\n", addr); + copied = access_process_vm(child, addr, &val, sizeof(val), 0); + rval = -EIO; + if (copied != sizeof(val)) + break; + rval = put_user(val, (unsigned long *)data); + break; + + case PTRACE_POKETEXT: /* write the word at location addr. */ + case PTRACE_POKEDATA: + pr_debug("POKETEXT/POKEDATA to %08lX\n", addr); + rval = 0; + if (access_process_vm(child, addr, &data, sizeof(data), 1) + == sizeof(data)) + break; + rval = -EIO; + break; + + /* Read/write the word at location ADDR in the registers. */ + case PTRACE_PEEKUSR: + case PTRACE_POKEUSR: + pr_debug("PEEKUSR/POKEUSR : 0x%08lx\n", addr); + rval = 0; + if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) { + /* + * Special requests that don't actually correspond + * to offsets in struct pt_regs. + */ + if (addr == PT_TEXT_ADDR) { + val = child->mm->start_code; + } else if (addr == PT_DATA_ADDR) { + val = child->mm->start_data; + } else if (addr == PT_TEXT_LEN) { + val = child->mm->end_code + - child->mm->start_code; + } else { + rval = -EIO; + } + } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) { + microblaze_reg_t *reg_addr = reg_save_addr(addr, child); + if (request == PTRACE_PEEKUSR) + val = *reg_addr; + else + *reg_addr = data; + } else + rval = -EIO; + + if (rval == 0 && request == PTRACE_PEEKUSR) + rval = put_user(val, (unsigned long *)data); + break; + /* Continue and stop at next (return from) syscall */ + case PTRACE_SYSCALL: + pr_debug("PTRACE_SYSCALL\n"); + case PTRACE_SINGLESTEP: + pr_debug("PTRACE_SINGLESTEP\n"); + /* Restart after a signal. */ + case PTRACE_CONT: + pr_debug("PTRACE_CONT\n"); + rval = -EIO; + if (!valid_signal(data)) + break; + + if (request == PTRACE_SYSCALL) + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + else + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + + child->exit_code = data; + pr_debug("wakeup_process\n"); + wake_up_process(child); + rval = 0; + break; + + /* + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to + * exit. + */ + case PTRACE_KILL: + pr_debug("PTRACE_KILL\n"); + rval = 0; + if (child->exit_state == EXIT_ZOMBIE) /* already dead */ + break; + child->exit_code = SIGKILL; + wake_up_process(child); + break; + + case PTRACE_DETACH: /* detach a process that was attached. */ + pr_debug("PTRACE_DETACH\n"); + rval = ptrace_detach(child, data); + break; + default: + /* rval = ptrace_request(child, request, addr, data); noMMU */ + rval = -EIO; + } + return rval; +} + +void ptrace_disable(struct task_struct *child) +{ + /* nothing to do */ +} diff --git a/arch/microblaze/kernel/selfmod.c b/arch/microblaze/kernel/selfmod.c new file mode 100644 index 0000000..89508bd --- /dev/null +++ b/arch/microblaze/kernel/selfmod.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2009 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/interrupt.h> +#include <asm/selfmod.h> + +#undef DEBUG + +#if __GNUC__ > 3 +#error GCC 4 unsupported SELFMOD. Please disable SELFMOD from menuconfig. +#endif + +#define OPCODE_IMM 0xB0000000 +#define OPCODE_LWI 0xE8000000 +#define OPCODE_LWI_MASK 0xEC000000 +#define OPCODE_RTSD 0xB60F0008 /* return from func: rtsd r15, 8 */ +#define OPCODE_ADDIK 0x30000000 +#define OPCODE_ADDIK_MASK 0xFC000000 + +#define IMM_BASE (OPCODE_IMM | (BARRIER_BASE_ADDR >> 16)) +#define LWI_BASE (OPCODE_LWI | (BARRIER_BASE_ADDR & 0x0000ff00)) +#define LWI_BASE_MASK (OPCODE_LWI_MASK | (BARRIER_BASE_ADDR & 0x0000ff00)) +#define ADDIK_BASE (OPCODE_ADDIK | (BARRIER_BASE_ADDR & 0x0000ff00)) +#define ADDIK_BASE_MASK (OPCODE_ADDIK_MASK | (BARRIER_BASE_ADDR & 0x0000ff00)) + +#define MODIFY_INSTR { \ + pr_debug("%s: curr instr, (%d):0x%x, next(%d):0x%x\n", \ + __func__, i, addr[i], i + 1, addr[i + 1]); \ + addr[i] = OPCODE_IMM + (base >> 16); \ + /* keep instruction opcode and add only last 16bits */ \ + addr[i + 1] = (addr[i + 1] & 0xffff00ff) + (base & 0xffff); \ + __invalidate_icache(addr[i]); \ + __invalidate_icache(addr[i + 1]); \ + pr_debug("%s: hack instr, (%d):0x%x, next(%d):0x%x\n", \ + __func__, i, addr[i], i + 1, addr[i + 1]); } + +/* NOTE + * self-modified part of code for improvement of interrupt controller + * save instruction in interrupt rutine + */ +void selfmod_function(const int *arr_fce, const unsigned int base) +{ + unsigned int flags, i, j, *addr = NULL; + + local_irq_save(flags); + __disable_icache(); + + /* zero terminated array */ + for (j = 0; arr_fce[j] != 0; j++) { + /* get start address of function */ + addr = (unsigned int *) arr_fce[j]; + pr_debug("%s: func(%d) at 0x%x\n", + __func__, j, (unsigned int) addr); + for (i = 0; ; i++) { + pr_debug("%s: instruction code at %d: 0x%x\n", + __func__, i, addr[i]); + if (addr[i] == IMM_BASE) { + /* detecting of lwi (0xE8) or swi (0xF8) instr + * I can detect both opcode with one mask */ + if ((addr[i + 1] & LWI_BASE_MASK) == LWI_BASE) { + MODIFY_INSTR; + } else /* detection addik for ack */ + if ((addr[i + 1] & ADDIK_BASE_MASK) == + ADDIK_BASE) { + MODIFY_INSTR; + } + } else if (addr[i] == OPCODE_RTSD) { + /* return from function means end of function */ + pr_debug("%s: end of array %d\n", __func__, i); + break; + } + } + } + local_irq_restore(flags); +} /* end of self-modified code */ diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c new file mode 100644 index 0000000..eb6b417 --- /dev/null +++ b/arch/microblaze/kernel/setup.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/string.h> +#include <linux/seq_file.h> +#include <linux/cpu.h> +#include <linux/initrd.h> +#include <linux/console.h> +#include <linux/debugfs.h> + +#include <asm/setup.h> +#include <asm/sections.h> +#include <asm/page.h> +#include <linux/io.h> +#include <linux/bug.h> +#include <linux/param.h> +#include <linux/cache.h> +#include <asm/cacheflush.h> +#include <asm/entry.h> +#include <asm/cpuinfo.h> + +#include <asm/system.h> +#include <asm/prom.h> +#include <asm/pgtable.h> + +DEFINE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */ +DEFINE_PER_CPU(unsigned int, KM); /* Kernel/user mode */ +DEFINE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */ +DEFINE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */ +DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ + +unsigned int boot_cpuid; +char cmd_line[COMMAND_LINE_SIZE]; + +void __init setup_arch(char **cmdline_p) +{ +#ifdef CONFIG_CMDLINE_FORCE + strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); + strlcpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); +#endif + *cmdline_p = cmd_line; + + console_verbose(); + + unflatten_device_tree(); + + /* NOTE I think that this function is not necessary to call */ + /* irq_early_init(); */ + setup_cpuinfo(); + + __invalidate_icache_all(); + __enable_icache(); + + __invalidate_dcache_all(); + __enable_dcache(); + + panic_timeout = 120; + + setup_memory(); + +#if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER) + printk(KERN_NOTICE "Self modified code enable\n"); +#endif + +#ifdef CONFIG_VT +#if defined(CONFIG_XILINX_CONSOLE) + conswitchp = &xil_con; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#endif +} + +#ifdef CONFIG_MTD_UCLINUX +/* Handle both romfs and cramfs types, without generating unnecessary + code (ie no point checking for CRAMFS if it's not even enabled) */ +inline unsigned get_romfs_len(unsigned *addr) +{ +#ifdef CONFIG_ROMFS_FS + if (memcmp(&addr[0], "-rom1fs-", 8) == 0) /* romfs */ + return be32_to_cpu(addr[2]); +#endif + +#ifdef CONFIG_CRAMFS + if (addr[0] == le32_to_cpu(0x28cd3d45)) /* cramfs */ + return le32_to_cpu(addr[1]); +#endif + return 0; +} +#endif /* CONFIG_MTD_UCLINUX_EBSS */ + +void __init machine_early_init(const char *cmdline, unsigned int ram, + unsigned int fdt) +{ + unsigned long *src, *dst = (unsigned long *)0x0; + +/* clearing bss section */ + memset(__bss_start, 0, __bss_stop-__bss_start); + memset(_ssbss, 0, _esbss-_ssbss); + + /* + * Copy command line passed from bootloader, or use default + * if none provided, or forced + */ +#ifndef CONFIG_CMDLINE_BOOL + if (cmdline && cmdline[0] != '\0') + strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE); +#endif + +/* initialize device tree for usage in early_printk */ + early_init_devtree((void *)_fdt_start); + +#ifdef CONFIG_EARLY_PRINTK + setup_early_printk(NULL); +#endif + + early_printk("Ramdisk addr 0x%08x, FDT 0x%08x\n", ram, fdt); + printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt); + +#ifdef CONFIG_MTD_UCLINUX + { + int size; + unsigned int romfs_base; + romfs_base = (ram ? ram : (unsigned int)&__init_end); + /* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is at the + * end of kernel, which is ROMFS_LOCATION defined above. */ + size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base)); + early_printk("Found romfs @ 0x%08x (0x%08x)\n", + romfs_base, size); + early_printk("#### klimit %p ####\n", klimit); + BUG_ON(size < 0); /* What else can we do? */ + + /* Use memmove to handle likely case of memory overlap */ + early_printk("Moving 0x%08x bytes from 0x%08x to 0x%08x\n", + size, romfs_base, (unsigned)&_ebss); + memmove(&_ebss, (int *)romfs_base, size); + + /* update klimit */ + klimit += PAGE_ALIGN(size); + early_printk("New klimit: 0x%08x\n", (unsigned)klimit); + } +#endif + + for (src = __ivt_start; src < __ivt_end; src++, dst++) + *dst = *src; + + /* Initialize global data */ + per_cpu(KM, 0) = 0x1; /* We start in kernel mode */ + per_cpu(CURRENT_SAVE, 0) = (unsigned long)current; +} + +#ifdef CONFIG_DEBUG_FS +struct dentry *of_debugfs_root; + +static int microblaze_debugfs_init(void) +{ + of_debugfs_root = debugfs_create_dir("microblaze", NULL); + + return of_debugfs_root == NULL; +} +arch_initcall(microblaze_debugfs_init); +#endif + +void machine_restart(char *cmd) +{ + printk(KERN_NOTICE "Machine restart...\n"); + dump_stack(); + while (1) + ; +} + +void machine_shutdown(void) +{ + printk(KERN_NOTICE "Machine shutdown...\n"); + while (1) + ; +} + +void machine_halt(void) +{ + printk(KERN_NOTICE "Machine halt...\n"); + while (1) + ; +} + +void machine_power_off(void) +{ + printk(KERN_NOTICE "Machine power off...\n"); + while (1) + ; +} diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c new file mode 100644 index 0000000..3889cf4 --- /dev/null +++ b/arch/microblaze/kernel/signal.c @@ -0,0 +1,537 @@ +/* + * Signal handling + * + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2003,2004 John Williams <jwilliams@itee.uq.edu.au> + * Copyright (C) 2001 NEC Corporation + * Copyright (C) 2001 Miles Bader <miles@gnu.org> + * Copyright (C) 1999,2000 Niibe Yutaka & Kaz Kojima + * Copyright (C) 1991,1992 Linus Torvalds + * + * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson + * + * This file was was derived from the sh version, arch/sh/kernel/signal.c + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/kernel.h> +#include <linux/signal.h> +#include <linux/errno.h> +#include <linux/wait.h> +#include <linux/ptrace.h> +#include <linux/unistd.h> +#include <linux/stddef.h> +#include <linux/personality.h> +#include <linux/percpu.h> +#include <linux/linkage.h> +#include <asm/entry.h> +#include <asm/ucontext.h> +#include <linux/uaccess.h> +#include <asm/pgtable.h> +#include <asm/pgalloc.h> +#include <linux/syscalls.h> +#include <asm/cacheflush.h> +#include <asm/syscalls.h> + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall); + +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +asmlinkage int +sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs) +{ + sigset_t saveset; + + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs->r3 = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(regs, &saveset, 1)) + return -EINTR; + } +} + +asmlinkage int +sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, + struct pt_regs *regs) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs->r3 = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(regs, &saveset, 1)) + return -EINTR; + } +} + +asmlinkage int +sys_sigaction(int sig, const struct old_sigaction *act, + struct old_sigaction *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} + +asmlinkage int +sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, + struct pt_regs *regs) +{ + return do_sigaltstack(uss, uoss, regs->r1); +} + +/* + * Do a signal return; undo the signal stack. + */ + +struct sigframe { + struct sigcontext sc; + unsigned long extramask[_NSIG_WORDS-1]; + unsigned long tramp[2]; /* signal trampoline */ +}; + +struct rt_sigframe { + struct siginfo info; + struct ucontext uc; + unsigned long tramp[2]; /* signal trampoline */ +}; + +static int +restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p) +{ + unsigned int err = 0; + +#define COPY(x) {err |= __get_user(regs->x, &sc->regs.x); } + COPY(r0); + COPY(r1); + COPY(r2); COPY(r3); COPY(r4); COPY(r5); + COPY(r6); COPY(r7); COPY(r8); COPY(r9); + COPY(r10); COPY(r11); COPY(r12); COPY(r13); + COPY(r14); COPY(r15); COPY(r16); COPY(r17); + COPY(r18); COPY(r19); COPY(r20); COPY(r21); + COPY(r22); COPY(r23); COPY(r24); COPY(r25); + COPY(r26); COPY(r27); COPY(r28); COPY(r29); + COPY(r30); COPY(r31); + COPY(pc); COPY(ear); COPY(esr); COPY(fsr); +#undef COPY + + *rval_p = regs->r3; + + return err; +} + +asmlinkage int sys_sigreturn(struct pt_regs *regs) +{ + struct sigframe *frame = (struct sigframe *)regs->r1; + sigset_t set; + int rval; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + + if (__get_user(set.sig[0], &frame->sc.oldmask) + || (_NSIG_WORDS > 1 + && __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->sc, &rval)) + goto badframe; + return rval; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) +{ + struct rt_sigframe *frame = (struct rt_sigframe *)regs->r1; + sigset_t set; + stack_t st; + int rval; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval)) + goto badframe; + + if (__copy_from_user((void *)&st, &frame->uc.uc_stack, sizeof(st))) + goto badframe; + /* It is more difficult to avoid calling this function than to + call it and ignore errors. */ + do_sigaltstack(&st, NULL, regs->r1); + + return rval; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +/* + * Set up a signal frame. + */ + +static int +setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, + unsigned long mask) +{ + int err = 0; + +#define COPY(x) {err |= __put_user(regs->x, &sc->regs.x); } + COPY(r0); + COPY(r1); + COPY(r2); COPY(r3); COPY(r4); COPY(r5); + COPY(r6); COPY(r7); COPY(r8); COPY(r9); + COPY(r10); COPY(r11); COPY(r12); COPY(r13); + COPY(r14); COPY(r15); COPY(r16); COPY(r17); + COPY(r18); COPY(r19); COPY(r20); COPY(r21); + COPY(r22); COPY(r23); COPY(r24); COPY(r25); + COPY(r26); COPY(r27); COPY(r28); COPY(r29); + COPY(r30); COPY(r31); + COPY(pc); COPY(ear); COPY(esr); COPY(fsr); +#undef COPY + + err |= __put_user(mask, &sc->oldmask); + + return err; +} + +/* + * Determine which stack to use.. + */ +static inline void * +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +{ + /* Default to using normal stack */ + unsigned long sp = regs->r1; + + if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp)) + sp = current->sas_ss_sp + current->sas_ss_size; + + return (void *)((sp - frame_size) & -8UL); +} + +static void setup_frame(int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs *regs) +{ + struct sigframe *frame; + int err = 0; + int signal; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto give_sigsegv; + + signal = current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain->signal_invmap[sig] + : sig; + + err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); + + if (_NSIG_WORDS > 1) { + err |= __copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + } + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + /* minus 8 is offset to cater for "rtsd r15,8" offset */ + if (ka->sa.sa_flags & SA_RESTORER) { + regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8; + } else { + /* Note, these encodings are _big endian_! */ + + /* addi r12, r0, __NR_sigreturn */ + err |= __put_user(0x31800000 | __NR_sigreturn , + frame->tramp + 0); + /* brki r14, 0x8 */ + err |= __put_user(0xb9cc0008, frame->tramp + 1); + + /* Return from sighandler will jump to the tramp. + Negative 8 offset because return is rtsd r15, 8 */ + regs->r15 = ((unsigned long)frame->tramp)-8; + + __invalidate_cache_sigtramp((unsigned long)frame->tramp); + } + + if (err) + goto give_sigsegv; + + /* Set up registers for signal handler */ + regs->r1 = (unsigned long) frame; + /* Signal handler args: */ + regs->r5 = signal; /* Arg 0: signum */ + regs->r6 = (unsigned long) &frame->sc; /* arg 1: sigcontext */ + + /* Offset of 4 to handle microblaze rtid r14, 0 */ + regs->pc = (unsigned long)ka->sa.sa_handler; + + set_fs(USER_DS); + +#ifdef DEBUG_SIG + printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n", + current->comm, current->pid, frame, regs->pc); +#endif + + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) +{ + struct rt_sigframe *frame; + int err = 0; + int signal; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto give_sigsegv; + + signal = current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap + && sig < 32 + ? current_thread_info()->exec_domain->signal_invmap[sig] + : sig; + + err |= copy_siginfo_to_user(&frame->info, info); + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user((void *)current->sas_ss_sp, + &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(regs->r1), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= setup_sigcontext(&frame->uc.uc_mcontext, + regs, set->sig[0]); + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + /* minus 8 is offset to cater for "rtsd r15,8" */ + if (ka->sa.sa_flags & SA_RESTORER) { + regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8; + } else { + /* addi r12, r0, __NR_sigreturn */ + err |= __put_user(0x31800000 | __NR_rt_sigreturn , + frame->tramp + 0); + /* brki r14, 0x8 */ + err |= __put_user(0xb9cc0008, frame->tramp + 1); + + /* Return from sighandler will jump to the tramp. + Negative 8 offset because return is rtsd r15, 8 */ + regs->r15 = ((unsigned long)frame->tramp)-8; + + __invalidate_cache_sigtramp((unsigned long)frame->tramp); + } + + if (err) + goto give_sigsegv; + + /* Set up registers for signal handler */ + regs->r1 = (unsigned long) frame; + /* Signal handler args: */ + regs->r5 = signal; /* arg 0: signum */ + regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */ + regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */ + /* Offset to handle microblaze rtid r14, 0 */ + regs->pc = (unsigned long)ka->sa.sa_handler; + + set_fs(USER_DS); + +#ifdef DEBUG_SIG + printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n", + current->comm, current->pid, frame, regs->pc); +#endif + + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +/* Handle restarting system calls */ +static inline void +handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) +{ + switch (regs->r3) { + case -ERESTART_RESTARTBLOCK: + case -ERESTARTNOHAND: + if (!has_handler) + goto do_restart; + regs->r3 = -EINTR; + break; + case -ERESTARTSYS: + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { + regs->r3 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: +do_restart: + /* offset of 4 bytes to re-execute trap (brki) instruction */ + regs->pc -= 4; + break; + } +} + +/* + * OK, we're invoking a handler + */ + +static void +handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) +{ + /* Set up the stack frame */ + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(sig, ka, info, oldset, regs); + else + setup_frame(sig, ka, oldset, regs); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, + ¤t->blocked, &ka->sa.sa_mask); + sigaddset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + * + * Note that we go through the signals twice: once to check the signals that + * the kernel can handle, and then we build all the user-level signal handling + * stack-frames in one go after that. + */ +int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) +{ + siginfo_t info; + int signr; + struct k_sigaction ka; +#ifdef DEBUG_SIG + printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall); + printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1, + regs->r12, current_thread_info()->flags); +#endif + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (kernel_mode(regs)) + return 1; + + if (!oldset) + oldset = ¤t->blocked; + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { + /* Whee! Actually deliver the signal. */ + if (in_syscall) + handle_restart(regs, &ka, 1); + handle_signal(signr, &ka, &info, oldset, regs); + return 1; + } + + if (in_syscall) + handle_restart(regs, NULL, 0); + + /* Did we come from a system call? */ + return 0; +} diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c new file mode 100644 index 0000000..ba0568c --- /dev/null +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2007 John Williams <john.williams@petalogix.com> + * + * Copyright (C) 2006 Atmark Techno, Inc. + * Yasushi SHOJI <yashi@atmark-techno.com> + * Tetsuya OHKAWA <tetsuya@atmark-techno.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/syscalls.h> +#include <linux/sem.h> +#include <linux/msg.h> +#include <linux/shm.h> +#include <linux/stat.h> +#include <linux/mman.h> +#include <linux/sys.h> +#include <linux/ipc.h> +#include <linux/utsname.h> +#include <linux/file.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/fs.h> +#include <linux/semaphore.h> +#include <linux/uaccess.h> +#include <linux/unistd.h> + +#include <asm/syscalls.h> +/* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. + * + * This is really horribly ugly. This will be remove with new toolchain. + */ +asmlinkage int +sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) +{ + int version, ret; + + version = call >> 16; /* hack for backward compatibility */ + call &= 0xffff; + + ret = -EINVAL; + switch (call) { + case SEMOP: + ret = sys_semop(first, (struct sembuf *)ptr, second); + break; + case SEMGET: + ret = sys_semget(first, second, third); + break; + case SEMCTL: + { + union semun fourth; + + if (!ptr) + break; + ret = (access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT) + || (get_user(fourth.__pad, (void **)ptr)) ; + if (ret) + break; + ret = sys_semctl(first, second, third, fourth); + break; + } + case MSGSND: + ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third); + break; + case MSGRCV: + switch (version) { + case 0: { + struct ipc_kludge tmp; + + if (!ptr) + break; + ret = (access_ok(VERIFY_READ, ptr, sizeof(tmp)) + ? 0 : -EFAULT) || copy_from_user(&tmp, + (struct ipc_kludge *) ptr, sizeof(tmp)); + if (ret) + break; + ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp, + third); + break; + } + default: + ret = sys_msgrcv(first, (struct msgbuf *) ptr, + second, fifth, third); + break; + } + break; + case MSGGET: + ret = sys_msgget((key_t) first, second); + break; + case MSGCTL: + ret = sys_msgctl(first, second, (struct msqid_ds *) ptr); + break; + case SHMAT: + switch (version) { + default: { + ulong raddr; + ret = access_ok(VERIFY_WRITE, (ulong *) third, + sizeof(ulong)) ? 0 : -EFAULT; + if (ret) + break; + ret = do_shmat(first, (char *) ptr, second, &raddr); + if (ret) + break; + ret = put_user(raddr, (ulong *) third); + break; + } + case 1: /* iBCS2 emulator entry point */ + if (!segment_eq(get_fs(), get_ds())) + break; + ret = do_shmat(first, (char *) ptr, second, + (ulong *) third); + break; + } + break; + case SHMDT: + ret = sys_shmdt((char *)ptr); + break; + case SHMGET: + ret = sys_shmget(first, second, third); + break; + case SHMCTL: + ret = sys_shmctl(first, second, (struct shmid_ds *) ptr); + break; + } + return -EINVAL; +} + +asmlinkage int sys_vfork(struct pt_regs *regs) +{ + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1, + regs, 0, NULL, NULL); +} + +asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs) +{ + if (!stack) + stack = regs->r1; + return do_fork(flags, stack, regs, 0, NULL, NULL); +} + +asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv, + char __user *__user *envp, struct pt_regs *regs) +{ + int error; + char *filename; + + filename = getname(filenamei); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = do_execve(filename, argv, envp, regs); + putname(filename); +out: + return error; +} + +asmlinkage unsigned long +sys_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + struct file *file = NULL; + int ret = -EBADF; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) { + printk(KERN_INFO "no fd in mmap\r\n"); + goto out; + } + } + + down_write(¤t->mm->mmap_sem); + ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + if (file) + fput(file); +out: + return ret; +} + +asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, off_t offset) +{ + int err = -EINVAL; + + if (offset & ~PAGE_MASK) { + printk(KERN_INFO "no pagemask in mmap\r\n"); + goto out; + } + + err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); +out: + return err; +} + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + register const char *__a __asm__("r5") = filename; + register const void *__b __asm__("r6") = argv; + register const void *__c __asm__("r7") = envp; + register unsigned long __syscall __asm__("r12") = __NR_execve; + register unsigned long __ret __asm__("r3"); + __asm__ __volatile__ ("brki r14, 0x8" + : "=r" (__ret), "=r" (__syscall) + : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) + : "r4", "r8", "r9", + "r10", "r11", "r14", "cc", "memory"); + return __ret; +} diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S new file mode 100644 index 0000000..529b0db --- /dev/null +++ b/arch/microblaze/kernel/syscall_table.S @@ -0,0 +1,365 @@ +ENTRY(sys_call_table) + .long sys_restart_syscall /* 0 - old "setup()" system call, + * used for restarting */ + .long sys_exit + .long sys_ni_syscall /* was fork */ + .long sys_read + .long sys_write + .long sys_open /* 5 */ + .long sys_close + .long sys_waitpid + .long sys_creat + .long sys_link + .long sys_unlink /* 10 */ + .long sys_execve_wrapper + .long sys_chdir + .long sys_time + .long sys_mknod + .long sys_chmod /* 15 */ + .long sys_lchown + .long sys_ni_syscall /* old break syscall holder */ + .long sys_ni_syscall /* old stat */ + .long sys_lseek + .long sys_getpid /* 20 */ + .long sys_mount + .long sys_oldumount + .long sys_setuid + .long sys_getuid + .long sys_stime /* 25 */ + .long sys_ptrace + .long sys_alarm + .long sys_ni_syscall /* oldfstat */ + .long sys_pause + .long sys_utime /* 30 */ + .long sys_ni_syscall /* old stty syscall holder */ + .long sys_ni_syscall /* old gtty syscall holder */ + .long sys_access + .long sys_nice + .long sys_ni_syscall /* 35 - old ftime syscall holder */ + .long sys_sync + .long sys_kill + .long sys_rename + .long sys_mkdir + .long sys_rmdir /* 40 */ + .long sys_dup + .long sys_pipe + .long sys_times + .long sys_ni_syscall /* old prof syscall holder */ + .long sys_brk /* 45 */ + .long sys_setgid + .long sys_getgid + .long sys_signal + .long sys_geteuid + .long sys_getegid /* 50 */ + .long sys_acct + .long sys_umount /* recycled never used phys() */ + .long sys_ni_syscall /* old lock syscall holder */ + .long sys_ioctl + .long sys_fcntl /* 55 */ + .long sys_ni_syscall /* old mpx syscall holder */ + .long sys_setpgid + .long sys_ni_syscall /* old ulimit syscall holder */ + .long sys_ni_syscall /* olduname */ + .long sys_umask /* 60 */ + .long sys_chroot + .long sys_ustat + .long sys_dup2 + .long sys_getppid + .long sys_getpgrp /* 65 */ + .long sys_setsid + .long sys_sigaction + .long sys_sgetmask + .long sys_ssetmask + .long sys_setreuid /* 70 */ + .long sys_setregid + .long sys_sigsuspend_wrapper + .long sys_sigpending + .long sys_sethostname + .long sys_setrlimit /* 75 */ + .long sys_ni_syscall /* old_getrlimit */ + .long sys_getrusage + .long sys_gettimeofday + .long sys_settimeofday + .long sys_getgroups /* 80 */ + .long sys_setgroups + .long sys_ni_syscall /* old_select */ + .long sys_symlink + .long sys_ni_syscall /* oldlstat */ + .long sys_readlink /* 85 */ + .long sys_uselib + .long sys_swapon + .long sys_reboot + .long sys_ni_syscall /* old_readdir */ + .long sys_mmap /* 90 */ /* old_mmap */ + .long sys_munmap + .long sys_truncate + .long sys_ftruncate + .long sys_fchmod + .long sys_fchown /* 95 */ + .long sys_getpriority + .long sys_setpriority + .long sys_ni_syscall /* old profil syscall holder */ + .long sys_statfs + .long sys_fstatfs /* 100 */ + .long sys_ni_syscall /* ioperm */ + .long sys_socketcall + .long sys_syslog /* operation with system console */ + .long sys_setitimer + .long sys_getitimer /* 105 */ + .long sys_newstat + .long sys_newlstat + .long sys_newfstat + .long sys_ni_syscall /* uname */ + .long sys_ni_syscall /* 110 */ /* iopl */ + .long sys_vhangup + .long sys_ni_syscall /* old "idle" system call */ + .long sys_ni_syscall /* old sys_vm86old */ + .long sys_wait4 + .long sys_swapoff /* 115 */ + .long sys_sysinfo + .long sys_ipc + .long sys_fsync + .long sys_sigreturn_wrapper + .long sys_clone_wrapper /* 120 */ + .long sys_setdomainname + .long sys_newuname + .long sys_ni_syscall /* modify_ldt */ + .long sys_adjtimex + .long sys_mprotect /* 125: sys_mprotect */ + .long sys_sigprocmask + .long sys_ni_syscall /* old "create_module" */ + .long sys_init_module + .long sys_delete_module + .long sys_ni_syscall /* 130: old "get_kernel_syms" */ + .long sys_quotactl + .long sys_getpgid + .long sys_fchdir + .long sys_bdflush + .long sys_sysfs /* 135 */ + .long sys_personality + .long sys_ni_syscall /* reserved for afs_syscall */ + .long sys_setfsuid + .long sys_setfsgid + .long sys_llseek /* 140 */ + .long sys_getdents + .long sys_select + .long sys_flock + .long sys_msync + .long sys_readv /* 145 */ + .long sys_writev + .long sys_getsid + .long sys_fdatasync + .long sys_sysctl + .long sys_mlock /* 150: sys_mlock */ + .long sys_munlock + .long sys_mlockall + .long sys_munlockall + .long sys_sched_setparam + .long sys_sched_getparam /* 155 */ + .long sys_sched_setscheduler + .long sys_sched_getscheduler + .long sys_sched_yield + .long sys_sched_get_priority_max + .long sys_sched_get_priority_min /* 160 */ + .long sys_sched_rr_get_interval + .long sys_nanosleep + .long sys_mremap + .long sys_setresuid + .long sys_getresuid /* 165 */ + .long sys_ni_syscall /* sys_vm86 */ + .long sys_ni_syscall /* Old sys_query_module */ + .long sys_poll + .long sys_nfsservctl + .long sys_setresgid /* 170 */ + .long sys_getresgid + .long sys_prctl + .long sys_rt_sigreturn_wrapper + .long sys_rt_sigaction + .long sys_rt_sigprocmask /* 175 */ + .long sys_rt_sigpending + .long sys_rt_sigtimedwait + .long sys_rt_sigqueueinfo + .long sys_rt_sigsuspend_wrapper + .long sys_pread64 /* 180 */ + .long sys_pwrite64 + .long sys_chown + .long sys_getcwd + .long sys_capget + .long sys_capset /* 185 */ + .long sys_ni_syscall /* sigaltstack */ + .long sys_sendfile + .long sys_ni_syscall /* reserved for streams1 */ + .long sys_ni_syscall /* reserved for streams2 */ + .long sys_vfork_wrapper /* 190 */ + .long sys_getrlimit + .long sys_mmap2 /* mmap2 */ + .long sys_truncate64 + .long sys_ftruncate64 + .long sys_stat64 /* 195 */ + .long sys_lstat64 + .long sys_fstat64 + .long sys_lchown + .long sys_getuid + .long sys_getgid /* 200 */ + .long sys_geteuid + .long sys_getegid + .long sys_setreuid + .long sys_setregid + .long sys_getgroups /* 205 */ + .long sys_setgroups + .long sys_fchown + .long sys_setresuid + .long sys_getresuid + .long sys_setresgid /* 210 */ + .long sys_getresgid + .long sys_chown + .long sys_setuid + .long sys_setgid + .long sys_setfsuid /* 215 */ + .long sys_setfsgid + .long sys_pivot_root + .long sys_mincore + .long sys_madvise + .long sys_getdents64 /* 220 */ + .long sys_fcntl64 + .long sys_ni_syscall /* reserved for TUX */ + .long sys_ni_syscall + .long sys_gettid + .long sys_readahead /* 225 */ + .long sys_setxattr + .long sys_lsetxattr + .long sys_fsetxattr + .long sys_getxattr + .long sys_lgetxattr /* 230 */ + .long sys_fgetxattr + .long sys_listxattr + .long sys_llistxattr + .long sys_flistxattr + .long sys_removexattr /* 235 */ + .long sys_lremovexattr + .long sys_fremovexattr + .long sys_tkill + .long sys_sendfile64 + .long sys_futex /* 240 */ + .long sys_sched_setaffinity + .long sys_sched_getaffinity + .long sys_ni_syscall /* set_thread_area */ + .long sys_ni_syscall /* get_thread_area */ + .long sys_io_setup /* 245 */ + .long sys_io_destroy + .long sys_io_getevents + .long sys_io_submit + .long sys_io_cancel + .long sys_fadvise64 /* 250 */ + .long sys_ni_syscall + .long sys_exit_group + .long sys_lookup_dcookie + .long sys_epoll_create + .long sys_epoll_ctl /* 255 */ + .long sys_epoll_wait + .long sys_remap_file_pages + .long sys_set_tid_address + .long sys_timer_create + .long sys_timer_settime /* 260 */ + .long sys_timer_gettime + .long sys_timer_getoverrun + .long sys_timer_delete + .long sys_clock_settime + .long sys_clock_gettime /* 265 */ + .long sys_clock_getres + .long sys_clock_nanosleep + .long sys_statfs64 + .long sys_fstatfs64 + .long sys_tgkill /* 270 */ + .long sys_utimes + .long sys_fadvise64_64 + .long sys_ni_syscall /* sys_vserver */ + .long sys_mbind + .long sys_get_mempolicy + .long sys_set_mempolicy + .long sys_mq_open + .long sys_mq_unlink + .long sys_mq_timedsend + .long sys_mq_timedreceive /* 280 */ + .long sys_mq_notify + .long sys_mq_getsetattr + .long sys_kexec_load + .long sys_waitid + .long sys_ni_syscall /* 285 */ /* available */ + .long sys_add_key + .long sys_request_key + .long sys_keyctl + .long sys_ioprio_set + .long sys_ioprio_get /* 290 */ + .long sys_inotify_init + .long sys_inotify_add_watch + .long sys_inotify_rm_watch + .long sys_ni_syscall /* sys_migrate_pages */ + .long sys_openat /* 295 */ + .long sys_mkdirat + .long sys_mknodat + .long sys_fchownat + .long sys_ni_syscall + .long sys_fstatat64 /* 300 */ + .long sys_unlinkat + .long sys_renameat + .long sys_linkat + .long sys_symlinkat + .long sys_readlinkat /* 305 */ + .long sys_fchmodat + .long sys_faccessat + .long sys_ni_syscall /* pselect6 */ + .long sys_ni_syscall /* sys_ppoll */ + .long sys_unshare /* 310 */ + .long sys_set_robust_list + .long sys_get_robust_list + .long sys_splice + .long sys_sync_file_range + .long sys_tee /* 315 */ + .long sys_vmsplice + .long sys_move_pages + .long sys_getcpu + .long sys_epoll_pwait + .long sys_utimensat /* 320 */ + .long sys_signalfd + .long sys_timerfd_create + .long sys_eventfd + .long sys_fallocate + .long sys_semtimedop /* 325 */ + .long sys_timerfd_settime + .long sys_timerfd_gettime + .long sys_semctl + .long sys_semget + .long sys_semop /* 330 */ + .long sys_msgctl + .long sys_msgget + .long sys_msgrcv + .long sys_msgsnd + .long sys_shmat /* 335 */ + .long sys_shmctl + .long sys_shmdt + .long sys_shmget + .long sys_signalfd4 /* new syscall */ + .long sys_eventfd2 /* 340 */ + .long sys_epoll_create1 + .long sys_dup3 + .long sys_pipe2 + .long sys_inotify_init1 + .long sys_socket /* 345 */ + .long sys_socketpair + .long sys_bind + .long sys_listen + .long sys_accept + .long sys_connect /* 350 */ + .long sys_getsockname + .long sys_getpeername + .long sys_sendto + .long sys_send + .long sys_recvfrom /* 355 */ + .long sys_recv + .long sys_setsockopt + .long sys_getsockopt + .long sys_shutdown + .long sys_sendmsg /* 360 */ + .long sys_recvmsg + .long sys_ni_syscall diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c new file mode 100644 index 0000000..05a497e --- /dev/null +++ b/arch/microblaze/kernel/timer.c @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/interrupt.h> +#include <linux/profile.h> +#include <linux/irq.h> +#include <linux/delay.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/clocksource.h> +#include <linux/clockchips.h> +#include <linux/io.h> +#include <asm/cpuinfo.h> +#include <asm/setup.h> +#include <asm/prom.h> +#include <asm/irq.h> +#include <asm/system.h> + +#ifdef CONFIG_SELFMOD_TIMER +#include <asm/selfmod.h> +#define TIMER_BASE BARRIER_BASE_ADDR +#else +static unsigned int timer_baseaddr; +#define TIMER_BASE timer_baseaddr +#endif + +#define TCSR0 (0x00) +#define TLR0 (0x04) +#define TCR0 (0x08) +#define TCSR1 (0x10) +#define TLR1 (0x14) +#define TCR1 (0x18) + +#define TCSR_MDT (1<<0) +#define TCSR_UDT (1<<1) +#define TCSR_GENT (1<<2) +#define TCSR_CAPT (1<<3) +#define TCSR_ARHT (1<<4) +#define TCSR_LOAD (1<<5) +#define TCSR_ENIT (1<<6) +#define TCSR_ENT (1<<7) +#define TCSR_TINT (1<<8) +#define TCSR_PWMA (1<<9) +#define TCSR_ENALL (1<<10) + +static inline void microblaze_timer0_stop(void) +{ + out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0) & ~TCSR_ENT); +} + +static inline void microblaze_timer0_start_periodic(unsigned long load_val) +{ + if (!load_val) + load_val = 1; + out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */ + + /* load the initial value */ + out_be32(TIMER_BASE + TCSR0, TCSR_LOAD); + + /* see timer data sheet for detail + * !ENALL - don't enable 'em all + * !PWMA - disable pwm + * TINT - clear interrupt status + * ENT- enable timer itself + * EINT - enable interrupt + * !LOAD - clear the bit to let go + * ARHT - auto reload + * !CAPT - no external trigger + * !GENT - no external signal + * UDT - set the timer as down counter + * !MDT0 - generate mode + */ + out_be32(TIMER_BASE + TCSR0, + TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT); +} + +static inline void microblaze_timer0_start_oneshot(unsigned long load_val) +{ + if (!load_val) + load_val = 1; + out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */ + + /* load the initial value */ + out_be32(TIMER_BASE + TCSR0, TCSR_LOAD); + + out_be32(TIMER_BASE + TCSR0, + TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT); +} + +static int microblaze_timer_set_next_event(unsigned long delta, + struct clock_event_device *dev) +{ + pr_debug("%s: next event, delta %x\n", __func__, (u32)delta); + microblaze_timer0_start_oneshot(delta); + return 0; +} + +static void microblaze_timer_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + printk(KERN_INFO "%s: periodic\n", __func__); + microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); + break; + case CLOCK_EVT_MODE_ONESHOT: + printk(KERN_INFO "%s: oneshot\n", __func__); + break; + case CLOCK_EVT_MODE_UNUSED: + printk(KERN_INFO "%s: unused\n", __func__); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + printk(KERN_INFO "%s: shutdown\n", __func__); + microblaze_timer0_stop(); + break; + case CLOCK_EVT_MODE_RESUME: + printk(KERN_INFO "%s: resume\n", __func__); + break; + } +} + +static struct clock_event_device clockevent_microblaze_timer = { + .name = "microblaze_clockevent", + .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, + .shift = 24, + .rating = 300, + .set_next_event = microblaze_timer_set_next_event, + .set_mode = microblaze_timer_set_mode, +}; + +static inline void timer_ack(void) +{ + out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0)); +} + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &clockevent_microblaze_timer; +#ifdef CONFIG_HEART_BEAT + heartbeat(); +#endif + timer_ack(); + evt->event_handler(evt); + return IRQ_HANDLED; +} + +static struct irqaction timer_irqaction = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED | IRQF_TIMER, + .name = "timer", + .dev_id = &clockevent_microblaze_timer, +}; + +static __init void microblaze_clockevent_init(void) +{ + clockevent_microblaze_timer.mult = + div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, + clockevent_microblaze_timer.shift); + clockevent_microblaze_timer.max_delta_ns = + clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); + clockevent_microblaze_timer.min_delta_ns = + clockevent_delta2ns(1, &clockevent_microblaze_timer); + clockevent_microblaze_timer.cpumask = cpumask_of(0); + clockevents_register_device(&clockevent_microblaze_timer); +} + +static cycle_t microblaze_read(void) +{ + /* reading actual value of timer 1 */ + return (cycle_t) (in_be32(TIMER_BASE + TCR1)); +} + +static struct clocksource clocksource_microblaze = { + .name = "microblaze_clocksource", + .rating = 300, + .read = microblaze_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 24, /* I can shift it */ + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init microblaze_clocksource_init(void) +{ + clocksource_microblaze.mult = + clocksource_hz2mult(cpuinfo.cpu_clock_freq, + clocksource_microblaze.shift); + if (clocksource_register(&clocksource_microblaze)) + panic("failed to register clocksource"); + + /* stop timer1 */ + out_be32(TIMER_BASE + TCSR1, in_be32(TIMER_BASE + TCSR1) & ~TCSR_ENT); + /* start timer1 - up counting without interrupt */ + out_be32(TIMER_BASE + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT); + return 0; +} + +void __init time_init(void) +{ + u32 irq, i = 0; + u32 timer_num = 1; + struct device_node *timer = NULL; +#ifdef CONFIG_SELFMOD_TIMER + unsigned int timer_baseaddr = 0; + int arr_func[] = { + (int)µblaze_read, + (int)&timer_interrupt, + (int)µblaze_clocksource_init, + (int)µblaze_timer_set_mode, + (int)µblaze_timer_set_next_event, + 0 + }; +#endif + char *timer_list[] = { + "xlnx,xps-timer-1.00.a", + "xlnx,opb-timer-1.00.b", + "xlnx,opb-timer-1.00.a", + NULL + }; + + for (i = 0; timer_list[i] != NULL; i++) { + timer = of_find_compatible_node(NULL, NULL, timer_list[i]); + if (timer) + break; + } + + timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); + timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); + irq = *(int *) of_get_property(timer, "interrupts", NULL); + timer_num = + *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); + if (timer_num) { + printk(KERN_EMERG "Please enable two timers in HW\n"); + BUG(); + } + +#ifdef CONFIG_SELFMOD_TIMER + selfmod_function((int *) arr_func, timer_baseaddr); +#endif + printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", + timer_list[i], timer_baseaddr, irq); + + cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; + + setup_irq(irq, &timer_irqaction); +#ifdef CONFIG_HEART_BEAT + setup_heartbeat(); +#endif + microblaze_clocksource_init(); + microblaze_clockevent_init(); +} diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c new file mode 100644 index 0000000..fbdc533 --- /dev/null +++ b/arch/microblaze/kernel/traps.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2007-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/kernel.h> +#include <linux/kallsyms.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/debug_locks.h> + +#include <asm/exceptions.h> +#include <asm/system.h> + +void trap_init(void) +{ + __enable_hw_exceptions(); +} + +void __bad_xchg(volatile void *ptr, int size) +{ + printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", + __builtin_return_address(0), ptr, size); + BUG(); +} +EXPORT_SYMBOL(__bad_xchg); + +static int kstack_depth_to_print = 24; + +static int __init kstack_setup(char *s) +{ + kstack_depth_to_print = strict_strtoul(s, 0, 0); + + return 1; +} +__setup("kstack=", kstack_setup); + +void show_trace(struct task_struct *task, unsigned long *stack) +{ + unsigned long addr; + + if (!stack) + stack = (unsigned long *)&stack; + + printk(KERN_NOTICE "Call Trace: "); +#ifdef CONFIG_KALLSYMS + printk(KERN_NOTICE "\n"); +#endif + while (!kstack_end(stack)) { + addr = *stack++; + /* + * If the address is either in the text segment of the + * kernel, or in the region which contains vmalloc'ed + * memory, it *may* be the address of a calling + * routine; if so, print it so that someone tracing + * down the cause of the crash will be able to figure + * out the call path that was taken. + */ + if (kernel_text_address(addr)) + print_ip_sym(addr); + } + printk(KERN_NOTICE "\n"); + + if (!task) + task = current; + + debug_show_held_locks(task); +} + +void show_stack(struct task_struct *task, unsigned long *sp) +{ + unsigned long *stack; + int i; + + if (sp == NULL) { + if (task) + sp = (unsigned long *) ((struct thread_info *) + (task->stack))->cpu_context.r1; + else + sp = (unsigned long *)&sp; + } + + stack = sp; + + printk(KERN_INFO "\nStack:\n "); + + for (i = 0; i < kstack_depth_to_print; i++) { + if (kstack_end(sp)) + break; + if (i && ((i % 8) == 0)) + printk("\n "); + printk("%08lx ", *sp++); + } + printk("\n"); + show_trace(task, stack); +} + +void dump_stack(void) +{ + show_stack(NULL, NULL); +} +EXPORT_SYMBOL(dump_stack); diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S new file mode 100644 index 0000000..840385e --- /dev/null +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze") +OUTPUT_ARCH(microblaze) +ENTRY(_start) + +#include <asm-generic/vmlinux.lds.h> + +jiffies = jiffies_64 + 4; + +SECTIONS { + . = CONFIG_KERNEL_BASE_ADDR; + + .text : { + _text = . ; + _stext = . ; + *(.text .text.*) + *(.fixup) + + *(.exitcall.exit) + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT + . = ALIGN (4) ; + _etext = . ; + } + + . = ALIGN (4) ; + _fdt_start = . ; /* place for fdt blob */ + . = . + 0x4000; + _fdt_end = . ; + + . = ALIGN(16); + RODATA + . = ALIGN(16); + __ex_table : { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + /* + * sdata2 section can go anywhere, but must be word aligned + * and SDA2_BASE must point to the middle of it + */ + .sdata2 : { + _ssrw = .; + . = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */ + *(.sdata2) + . = ALIGN(8); + _essrw = .; + _ssrw_size = _essrw - _ssrw; + _KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2); + } + + _sdata = . ; + .data ALIGN (4096) : { /* page aligned when MMU used - origin 0x4 */ + *(.data) + } + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + _edata = . ; + + /* Reserve some low RAM for r0 based memory references */ + . = ALIGN(0x4) ; + r0_ram = . ; + . = . + 4096; /* a page should be enough */ + + /* The initial task */ + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + /* Under the microblaze ABI, .sdata and .sbss must be contiguous */ + . = ALIGN(8); + .sdata : { + _ssro = .; + *(.sdata) + } + + .sbss : { + _ssbss = .; + *(.sbss) + _esbss = .; + _essro = .; + _ssro_size = _essro - _ssro ; + _KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ; + } + + __init_begin = .; + + . = ALIGN(4096); + .init.text : { + _sinittext = . ; + *(.init.text) + *(.exit.text) + *(.exit.data) + _einittext = .; + } + + .init.data : { *(.init.data) } + + . = ALIGN(4); + .init.ivt : { + __ivt_start = .; + *(.init.ivt) + __ivt_end = .; + } + + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + + .initcall.init : { + __initcall_start = .; + INITCALLS + __initcall_end = .; + } + + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + + __init_end_before_initramfs = .; + + .init.ramfs ALIGN(4096) : { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + . = ALIGN(4); + LONG(0); +/* + * FIXME this can break initramfs for MMU. + * Pad init.ramfs up to page boundary, + * so that __init_end == __bss_start. This will make image.elf + * consistent with the image.bin + */ + /* . = ALIGN(4096); */ + } + __init_end = .; + + .bss ALIGN (4096) : { /* page aligned when MMU used */ + __bss_start = . ; + *(.bss*) + *(COMMON) + . = ALIGN (4) ; + __bss_stop = . ; + _ebss = . ; + } + . = ALIGN(4096); + _end = .; +} diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile new file mode 100644 index 0000000..d27126b --- /dev/null +++ b/arch/microblaze/lib/Makefile @@ -0,0 +1,13 @@ +# +# Makefile +# + +lib-y := memset.o checksum.o + +ifeq ($(CONFIG_OPT_LIB_ASM),y) +lib-y += fastcopy.o +else +lib-y += memcpy.o memmove.o +endif + +lib-y += uaccess.o diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c new file mode 100644 index 0000000..8093400 --- /dev/null +++ b/arch/microblaze/lib/checksum.c @@ -0,0 +1,163 @@ +/* + * + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * IP/TCP/UDP checksumming routines + * + * Authors: Jorge Cwik, <jorge@laser.satlink.net> + * Arnt Gulbrandsen, <agulbra@nvg.unit.no> + * Tom May, <ftom@netcom.com> + * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de> + * Lots of code moved from tcp.c and ip.c; see those files + * for more names. + * + * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: + * Fixed some nasty bugs, causing some horrible crashes. + * A: At some points, the sum (%0) was used as + * length-counter instead of the length counter + * (%1). Thanks to Roman Hodek for pointing this out. + * B: GCC seems to mess up if one uses too many + * data-registers to hold input values and one tries to + * specify d0 and d1 as scratch registers. Letting gcc + * choose these registers itself solves the problem. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access + kills, so most of the assembly has to go. */ + +#include <net/checksum.h> +#include <asm/checksum.h> +#include <linux/module.h> + +static inline unsigned short from32to16(unsigned long x) +{ + /* add up 16-bit and 16-bit for 16+c bit */ + x = (x & 0xffff) + (x >> 16); + /* add up carry.. */ + x = (x & 0xffff) + (x >> 16); + return x; +} + +static unsigned int do_csum(const unsigned char *buff, int len) +{ + int odd, count; + unsigned long result = 0; + + if (len <= 0) + goto out; + odd = 1 & (unsigned long) buff; + if (odd) { + result = *buff; + len--; + buff++; + } + count = len >> 1; /* nr of 16-bit words.. */ + if (count) { + if (2 & (unsigned long) buff) { + result += *(unsigned short *) buff; + count--; + len -= 2; + buff += 2; + } + count >>= 1; /* nr of 32-bit words.. */ + if (count) { + unsigned long carry = 0; + do { + unsigned long w = *(unsigned long *) buff; + count--; + buff += 4; + result += carry; + result += w; + carry = (w > result); + } while (count); + result += carry; + result = (result & 0xffff) + (result >> 16); + } + if (len & 2) { + result += *(unsigned short *) buff; + buff += 2; + } + } + if (len & 1) + result += (*buff << 8); + result = from32to16(result); + if (odd) + result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); +out: + return result; +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +__sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + return (__force __sum16)~do_csum(iph, ihl*4); +} + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum) +{ + unsigned int result = do_csum(buff, len); + + /* add in old sum, and carry.. */ + result += sum; + if (sum > result) + result += 1; + return result; +} +EXPORT_SYMBOL(csum_partial); + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +__sum16 ip_compute_csum(const unsigned char *buff, int len) +{ + return ~do_csum(buff, len); +} +EXPORT_SYMBOL(ip_compute_csum); + +/* + * copy from fs while checksumming, otherwise like csum_partial + */ +__wsum +csum_partial_copy_from_user(const char __user *src, char *dst, int len, + int sum, int *csum_err) +{ + if (csum_err) + *csum_err = 0; + memcpy(dst, src, len); + return csum_partial(dst, len, sum); +} +EXPORT_SYMBOL(csum_partial_copy_from_user); + +/* + * copy from ds while checksumming, otherwise like csum_partial + */ +__wsum +csum_partial_copy(const char *src, char *dst, int len, int sum) +{ + memcpy(dst, src, len); + return csum_partial(dst, len, sum); +} +EXPORT_SYMBOL(csum_partial_copy); diff --git a/arch/microblaze/lib/fastcopy.S b/arch/microblaze/lib/fastcopy.S new file mode 100644 index 0000000..02e3ab4 --- /dev/null +++ b/arch/microblaze/lib/fastcopy.S @@ -0,0 +1,662 @@ +/* + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2008 Jim Law - Iris LP All rights reserved. + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + * + * Written by Jim Law <jlaw@irispower.com> + * + * intended to replace: + * memcpy in memcpy.c and + * memmove in memmove.c + * ... in arch/microblaze/lib + * + * + * assly_fastcopy.S + * + * Attempt at quicker memcpy and memmove for MicroBlaze + * Input : Operand1 in Reg r5 - destination address + * Operand2 in Reg r6 - source address + * Operand3 in Reg r7 - number of bytes to transfer + * Output: Result in Reg r3 - starting destinaition address + * + * + * Explanation: + * Perform (possibly unaligned) copy of a block of memory + * between mem locations with size of xfer spec'd in bytes + */ + +#include <linux/linkage.h> + + .globl memcpy + .ent memcpy + +memcpy: +fast_memcpy_ascending: + /* move d to return register as value of function */ + addi r3, r5, 0 + + addi r4, r0, 4 /* n = 4 */ + cmpu r4, r4, r7 /* n = c - n (unsigned) */ + blti r4, a_xfer_end /* if n < 0, less than one word to transfer */ + + /* transfer first 0~3 bytes to get aligned dest address */ + andi r4, r5, 3 /* n = d & 3 */ + /* if zero, destination already aligned */ + beqi r4, a_dalign_done + /* n = 4 - n (yields 3, 2, 1 transfers for 1, 2, 3 addr offset) */ + rsubi r4, r4, 4 + rsub r7, r4, r7 /* c = c - n adjust c */ + +a_xfer_first_loop: + /* if no bytes left to transfer, transfer the bulk */ + beqi r4, a_dalign_done + lbui r11, r6, 0 /* h = *s */ + sbi r11, r5, 0 /* *d = h */ + addi r6, r6, 1 /* s++ */ + addi r5, r5, 1 /* d++ */ + brid a_xfer_first_loop /* loop */ + addi r4, r4, -1 /* n-- (IN DELAY SLOT) */ + +a_dalign_done: + addi r4, r0, 32 /* n = 32 */ + cmpu r4, r4, r7 /* n = c - n (unsigned) */ + /* if n < 0, less than one block to transfer */ + blti r4, a_block_done + +a_block_xfer: + andi r4, r7, 0xffffffe0 /* n = c & ~31 */ + rsub r7, r4, r7 /* c = c - n */ + + andi r9, r6, 3 /* t1 = s & 3 */ + /* if temp != 0, unaligned transfers needed */ + bnei r9, a_block_unaligned + +a_block_aligned: + lwi r9, r6, 0 /* t1 = *(s + 0) */ + lwi r10, r6, 4 /* t2 = *(s + 4) */ + lwi r11, r6, 8 /* t3 = *(s + 8) */ + lwi r12, r6, 12 /* t4 = *(s + 12) */ + swi r9, r5, 0 /* *(d + 0) = t1 */ + swi r10, r5, 4 /* *(d + 4) = t2 */ + swi r11, r5, 8 /* *(d + 8) = t3 */ + swi r12, r5, 12 /* *(d + 12) = t4 */ + lwi r9, r6, 16 /* t1 = *(s + 16) */ + lwi r10, r6, 20 /* t2 = *(s + 20) */ + lwi r11, r6, 24 /* t3 = *(s + 24) */ + lwi r12, r6, 28 /* t4 = *(s + 28) */ + swi r9, r5, 16 /* *(d + 16) = t1 */ + swi r10, r5, 20 /* *(d + 20) = t2 */ + swi r11, r5, 24 /* *(d + 24) = t3 */ + swi r12, r5, 28 /* *(d + 28) = t4 */ + addi r6, r6, 32 /* s = s + 32 */ + addi r4, r4, -32 /* n = n - 32 */ + bneid r4, a_block_aligned /* while (n) loop */ + addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */ + bri a_block_done + +a_block_unaligned: + andi r8, r6, 0xfffffffc /* as = s & ~3 */ + add r6, r6, r4 /* s = s + n */ + lwi r11, r8, 0 /* h = *(as + 0) */ + + addi r9, r9, -1 + beqi r9, a_block_u1 /* t1 was 1 => 1 byte offset */ + addi r9, r9, -1 + beqi r9, a_block_u2 /* t1 was 2 => 2 byte offset */ + +a_block_u3: + bslli r11, r11, 24 /* h = h << 24 */ +a_bu3_loop: + lwi r12, r8, 4 /* v = *(as + 4) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 0 /* *(d + 0) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + lwi r12, r8, 8 /* v = *(as + 8) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 4 /* *(d + 4) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + lwi r12, r8, 12 /* v = *(as + 12) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 8 /* *(d + 8) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + lwi r12, r8, 16 /* v = *(as + 16) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 12 /* *(d + 12) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + lwi r12, r8, 20 /* v = *(as + 20) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 16 /* *(d + 16) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + lwi r12, r8, 24 /* v = *(as + 24) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 20 /* *(d + 20) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + lwi r12, r8, 28 /* v = *(as + 28) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 24 /* *(d + 24) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + lwi r12, r8, 32 /* v = *(as + 32) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 28 /* *(d + 28) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + addi r8, r8, 32 /* as = as + 32 */ + addi r4, r4, -32 /* n = n - 32 */ + bneid r4, a_bu3_loop /* while (n) loop */ + addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */ + bri a_block_done + +a_block_u1: + bslli r11, r11, 8 /* h = h << 8 */ +a_bu1_loop: + lwi r12, r8, 4 /* v = *(as + 4) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 0 /* *(d + 0) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + lwi r12, r8, 8 /* v = *(as + 8) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 4 /* *(d + 4) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + lwi r12, r8, 12 /* v = *(as + 12) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 8 /* *(d + 8) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + lwi r12, r8, 16 /* v = *(as + 16) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 12 /* *(d + 12) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + lwi r12, r8, 20 /* v = *(as + 20) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 16 /* *(d + 16) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + lwi r12, r8, 24 /* v = *(as + 24) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 20 /* *(d + 20) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + lwi r12, r8, 28 /* v = *(as + 28) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 24 /* *(d + 24) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + lwi r12, r8, 32 /* v = *(as + 32) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 28 /* *(d + 28) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + addi r8, r8, 32 /* as = as + 32 */ + addi r4, r4, -32 /* n = n - 32 */ + bneid r4, a_bu1_loop /* while (n) loop */ + addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */ + bri a_block_done + +a_block_u2: + bslli r11, r11, 16 /* h = h << 16 */ +a_bu2_loop: + lwi r12, r8, 4 /* v = *(as + 4) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 0 /* *(d + 0) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + lwi r12, r8, 8 /* v = *(as + 8) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 4 /* *(d + 4) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + lwi r12, r8, 12 /* v = *(as + 12) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 8 /* *(d + 8) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + lwi r12, r8, 16 /* v = *(as + 16) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 12 /* *(d + 12) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + lwi r12, r8, 20 /* v = *(as + 20) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 16 /* *(d + 16) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + lwi r12, r8, 24 /* v = *(as + 24) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 20 /* *(d + 20) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + lwi r12, r8, 28 /* v = *(as + 28) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 24 /* *(d + 24) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + lwi r12, r8, 32 /* v = *(as + 32) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 28 /* *(d + 28) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + addi r8, r8, 32 /* as = as + 32 */ + addi r4, r4, -32 /* n = n - 32 */ + bneid r4, a_bu2_loop /* while (n) loop */ + addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */ + +a_block_done: + addi r4, r0, 4 /* n = 4 */ + cmpu r4, r4, r7 /* n = c - n (unsigned) */ + blti r4, a_xfer_end /* if n < 0, less than one word to transfer */ + +a_word_xfer: + andi r4, r7, 0xfffffffc /* n = c & ~3 */ + addi r10, r0, 0 /* offset = 0 */ + + andi r9, r6, 3 /* t1 = s & 3 */ + /* if temp != 0, unaligned transfers needed */ + bnei r9, a_word_unaligned + +a_word_aligned: + lw r9, r6, r10 /* t1 = *(s+offset) */ + sw r9, r5, r10 /* *(d+offset) = t1 */ + addi r4, r4,-4 /* n-- */ + bneid r4, a_word_aligned /* loop */ + addi r10, r10, 4 /* offset++ (IN DELAY SLOT) */ + + bri a_word_done + +a_word_unaligned: + andi r8, r6, 0xfffffffc /* as = s & ~3 */ + lwi r11, r8, 0 /* h = *(as + 0) */ + addi r8, r8, 4 /* as = as + 4 */ + + addi r9, r9, -1 + beqi r9, a_word_u1 /* t1 was 1 => 1 byte offset */ + addi r9, r9, -1 + beqi r9, a_word_u2 /* t1 was 2 => 2 byte offset */ + +a_word_u3: + bslli r11, r11, 24 /* h = h << 24 */ +a_wu3_loop: + lw r12, r8, r10 /* v = *(as + offset) */ + bsrli r9, r12, 8 /* t1 = v >> 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + sw r9, r5, r10 /* *(d + offset) = t1 */ + bslli r11, r12, 24 /* h = v << 24 */ + addi r4, r4,-4 /* n = n - 4 */ + bneid r4, a_wu3_loop /* while (n) loop */ + addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */ + + bri a_word_done + +a_word_u1: + bslli r11, r11, 8 /* h = h << 8 */ +a_wu1_loop: + lw r12, r8, r10 /* v = *(as + offset) */ + bsrli r9, r12, 24 /* t1 = v >> 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + sw r9, r5, r10 /* *(d + offset) = t1 */ + bslli r11, r12, 8 /* h = v << 8 */ + addi r4, r4,-4 /* n = n - 4 */ + bneid r4, a_wu1_loop /* while (n) loop */ + addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */ + + bri a_word_done + +a_word_u2: + bslli r11, r11, 16 /* h = h << 16 */ +a_wu2_loop: + lw r12, r8, r10 /* v = *(as + offset) */ + bsrli r9, r12, 16 /* t1 = v >> 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + sw r9, r5, r10 /* *(d + offset) = t1 */ + bslli r11, r12, 16 /* h = v << 16 */ + addi r4, r4,-4 /* n = n - 4 */ + bneid r4, a_wu2_loop /* while (n) loop */ + addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */ + +a_word_done: + add r5, r5, r10 /* d = d + offset */ + add r6, r6, r10 /* s = s + offset */ + rsub r7, r10, r7 /* c = c - offset */ + +a_xfer_end: +a_xfer_end_loop: + beqi r7, a_done /* while (c) */ + lbui r9, r6, 0 /* t1 = *s */ + addi r6, r6, 1 /* s++ */ + sbi r9, r5, 0 /* *d = t1 */ + addi r7, r7, -1 /* c-- */ + brid a_xfer_end_loop /* loop */ + addi r5, r5, 1 /* d++ (IN DELAY SLOT) */ + +a_done: + rtsd r15, 8 + nop + +.end memcpy +/*----------------------------------------------------------------------------*/ + .globl memmove + .ent memmove + +memmove: + cmpu r4, r5, r6 /* n = s - d */ + bgei r4,fast_memcpy_ascending + +fast_memcpy_descending: + /* move d to return register as value of function */ + addi r3, r5, 0 + + add r5, r5, r7 /* d = d + c */ + add r6, r6, r7 /* s = s + c */ + + addi r4, r0, 4 /* n = 4 */ + cmpu r4, r4, r7 /* n = c - n (unsigned) */ + blti r4,d_xfer_end /* if n < 0, less than one word to transfer */ + + /* transfer first 0~3 bytes to get aligned dest address */ + andi r4, r5, 3 /* n = d & 3 */ + /* if zero, destination already aligned */ + beqi r4,d_dalign_done + rsub r7, r4, r7 /* c = c - n adjust c */ + +d_xfer_first_loop: + /* if no bytes left to transfer, transfer the bulk */ + beqi r4,d_dalign_done + addi r6, r6, -1 /* s-- */ + addi r5, r5, -1 /* d-- */ + lbui r11, r6, 0 /* h = *s */ + sbi r11, r5, 0 /* *d = h */ + brid d_xfer_first_loop /* loop */ + addi r4, r4, -1 /* n-- (IN DELAY SLOT) */ + +d_dalign_done: + addi r4, r0, 32 /* n = 32 */ + cmpu r4, r4, r7 /* n = c - n (unsigned) */ + /* if n < 0, less than one block to transfer */ + blti r4, d_block_done + +d_block_xfer: + andi r4, r7, 0xffffffe0 /* n = c & ~31 */ + rsub r7, r4, r7 /* c = c - n */ + + andi r9, r6, 3 /* t1 = s & 3 */ + /* if temp != 0, unaligned transfers needed */ + bnei r9, d_block_unaligned + +d_block_aligned: + addi r6, r6, -32 /* s = s - 32 */ + addi r5, r5, -32 /* d = d - 32 */ + lwi r9, r6, 28 /* t1 = *(s + 28) */ + lwi r10, r6, 24 /* t2 = *(s + 24) */ + lwi r11, r6, 20 /* t3 = *(s + 20) */ + lwi r12, r6, 16 /* t4 = *(s + 16) */ + swi r9, r5, 28 /* *(d + 28) = t1 */ + swi r10, r5, 24 /* *(d + 24) = t2 */ + swi r11, r5, 20 /* *(d + 20) = t3 */ + swi r12, r5, 16 /* *(d + 16) = t4 */ + lwi r9, r6, 12 /* t1 = *(s + 12) */ + lwi r10, r6, 8 /* t2 = *(s + 8) */ + lwi r11, r6, 4 /* t3 = *(s + 4) */ + lwi r12, r6, 0 /* t4 = *(s + 0) */ + swi r9, r5, 12 /* *(d + 12) = t1 */ + swi r10, r5, 8 /* *(d + 8) = t2 */ + swi r11, r5, 4 /* *(d + 4) = t3 */ + addi r4, r4, -32 /* n = n - 32 */ + bneid r4, d_block_aligned /* while (n) loop */ + swi r12, r5, 0 /* *(d + 0) = t4 (IN DELAY SLOT) */ + bri d_block_done + +d_block_unaligned: + andi r8, r6, 0xfffffffc /* as = s & ~3 */ + rsub r6, r4, r6 /* s = s - n */ + lwi r11, r8, 0 /* h = *(as + 0) */ + + addi r9, r9, -1 + beqi r9,d_block_u1 /* t1 was 1 => 1 byte offset */ + addi r9, r9, -1 + beqi r9,d_block_u2 /* t1 was 2 => 2 byte offset */ + +d_block_u3: + bsrli r11, r11, 8 /* h = h >> 8 */ +d_bu3_loop: + addi r8, r8, -32 /* as = as - 32 */ + addi r5, r5, -32 /* d = d - 32 */ + lwi r12, r8, 28 /* v = *(as + 28) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 28 /* *(d + 28) = t1 */ + bsrli r11, r12, 8 /* h = v >> 8 */ + lwi r12, r8, 24 /* v = *(as + 24) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 24 /* *(d + 24) = t1 */ + bsrli r11, r12, 8 /* h = v >> 8 */ + lwi r12, r8, 20 /* v = *(as + 20) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 20 /* *(d + 20) = t1 */ + bsrli r11, r12, 8 /* h = v >> 8 */ + lwi r12, r8, 16 /* v = *(as + 16) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 16 /* *(d + 16) = t1 */ + bsrli r11, r12, 8 /* h = v >> 8 */ + lwi r12, r8, 12 /* v = *(as + 12) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 12 /* *(d + 112) = t1 */ + bsrli r11, r12, 8 /* h = v >> 8 */ + lwi r12, r8, 8 /* v = *(as + 8) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 8 /* *(d + 8) = t1 */ + bsrli r11, r12, 8 /* h = v >> 8 */ + lwi r12, r8, 4 /* v = *(as + 4) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 4 /* *(d + 4) = t1 */ + bsrli r11, r12, 8 /* h = v >> 8 */ + lwi r12, r8, 0 /* v = *(as + 0) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 0 /* *(d + 0) = t1 */ + addi r4, r4, -32 /* n = n - 32 */ + bneid r4, d_bu3_loop /* while (n) loop */ + bsrli r11, r12, 8 /* h = v >> 8 (IN DELAY SLOT) */ + bri d_block_done + +d_block_u1: + bsrli r11, r11, 24 /* h = h >> 24 */ +d_bu1_loop: + addi r8, r8, -32 /* as = as - 32 */ + addi r5, r5, -32 /* d = d - 32 */ + lwi r12, r8, 28 /* v = *(as + 28) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 28 /* *(d + 28) = t1 */ + bsrli r11, r12, 24 /* h = v >> 24 */ + lwi r12, r8, 24 /* v = *(as + 24) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 24 /* *(d + 24) = t1 */ + bsrli r11, r12, 24 /* h = v >> 24 */ + lwi r12, r8, 20 /* v = *(as + 20) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 20 /* *(d + 20) = t1 */ + bsrli r11, r12, 24 /* h = v >> 24 */ + lwi r12, r8, 16 /* v = *(as + 16) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 16 /* *(d + 16) = t1 */ + bsrli r11, r12, 24 /* h = v >> 24 */ + lwi r12, r8, 12 /* v = *(as + 12) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 12 /* *(d + 112) = t1 */ + bsrli r11, r12, 24 /* h = v >> 24 */ + lwi r12, r8, 8 /* v = *(as + 8) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 8 /* *(d + 8) = t1 */ + bsrli r11, r12, 24 /* h = v >> 24 */ + lwi r12, r8, 4 /* v = *(as + 4) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 4 /* *(d + 4) = t1 */ + bsrli r11, r12, 24 /* h = v >> 24 */ + lwi r12, r8, 0 /* v = *(as + 0) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 0 /* *(d + 0) = t1 */ + addi r4, r4, -32 /* n = n - 32 */ + bneid r4, d_bu1_loop /* while (n) loop */ + bsrli r11, r12, 24 /* h = v >> 24 (IN DELAY SLOT) */ + bri d_block_done + +d_block_u2: + bsrli r11, r11, 16 /* h = h >> 16 */ +d_bu2_loop: + addi r8, r8, -32 /* as = as - 32 */ + addi r5, r5, -32 /* d = d - 32 */ + lwi r12, r8, 28 /* v = *(as + 28) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 28 /* *(d + 28) = t1 */ + bsrli r11, r12, 16 /* h = v >> 16 */ + lwi r12, r8, 24 /* v = *(as + 24) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 24 /* *(d + 24) = t1 */ + bsrli r11, r12, 16 /* h = v >> 16 */ + lwi r12, r8, 20 /* v = *(as + 20) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 20 /* *(d + 20) = t1 */ + bsrli r11, r12, 16 /* h = v >> 16 */ + lwi r12, r8, 16 /* v = *(as + 16) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 16 /* *(d + 16) = t1 */ + bsrli r11, r12, 16 /* h = v >> 16 */ + lwi r12, r8, 12 /* v = *(as + 12) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 12 /* *(d + 112) = t1 */ + bsrli r11, r12, 16 /* h = v >> 16 */ + lwi r12, r8, 8 /* v = *(as + 8) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 8 /* *(d + 8) = t1 */ + bsrli r11, r12, 16 /* h = v >> 16 */ + lwi r12, r8, 4 /* v = *(as + 4) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 4 /* *(d + 4) = t1 */ + bsrli r11, r12, 16 /* h = v >> 16 */ + lwi r12, r8, 0 /* v = *(as + 0) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + swi r9, r5, 0 /* *(d + 0) = t1 */ + addi r4, r4, -32 /* n = n - 32 */ + bneid r4, d_bu2_loop /* while (n) loop */ + bsrli r11, r12, 16 /* h = v >> 16 (IN DELAY SLOT) */ + +d_block_done: + addi r4, r0, 4 /* n = 4 */ + cmpu r4, r4, r7 /* n = c - n (unsigned) */ + blti r4,d_xfer_end /* if n < 0, less than one word to transfer */ + +d_word_xfer: + andi r4, r7, 0xfffffffc /* n = c & ~3 */ + rsub r5, r4, r5 /* d = d - n */ + rsub r6, r4, r6 /* s = s - n */ + rsub r7, r4, r7 /* c = c - n */ + + andi r9, r6, 3 /* t1 = s & 3 */ + /* if temp != 0, unaligned transfers needed */ + bnei r9, d_word_unaligned + +d_word_aligned: + addi r4, r4,-4 /* n-- */ + lw r9, r6, r4 /* t1 = *(s+n) */ + bneid r4, d_word_aligned /* loop */ + sw r9, r5, r4 /* *(d+n) = t1 (IN DELAY SLOT) */ + + bri d_word_done + +d_word_unaligned: + andi r8, r6, 0xfffffffc /* as = s & ~3 */ + lw r11, r8, r4 /* h = *(as + n) */ + + addi r9, r9, -1 + beqi r9,d_word_u1 /* t1 was 1 => 1 byte offset */ + addi r9, r9, -1 + beqi r9,d_word_u2 /* t1 was 2 => 2 byte offset */ + +d_word_u3: + bsrli r11, r11, 8 /* h = h >> 8 */ +d_wu3_loop: + addi r4, r4,-4 /* n = n - 4 */ + lw r12, r8, r4 /* v = *(as + n) */ + bslli r9, r12, 24 /* t1 = v << 24 */ + or r9, r11, r9 /* t1 = h | t1 */ + sw r9, r5, r4 /* *(d + n) = t1 */ + bneid r4, d_wu3_loop /* while (n) loop */ + bsrli r11, r12, 8 /* h = v >> 8 (IN DELAY SLOT) */ + + bri d_word_done + +d_word_u1: + bsrli r11, r11, 24 /* h = h >> 24 */ +d_wu1_loop: + addi r4, r4,-4 /* n = n - 4 */ + lw r12, r8, r4 /* v = *(as + n) */ + bslli r9, r12, 8 /* t1 = v << 8 */ + or r9, r11, r9 /* t1 = h | t1 */ + sw r9, r5, r4 /* *(d + n) = t1 */ + bneid r4, d_wu1_loop /* while (n) loop */ + bsrli r11, r12, 24 /* h = v >> 24 (IN DELAY SLOT) */ + + bri d_word_done + +d_word_u2: + bsrli r11, r11, 16 /* h = h >> 16 */ +d_wu2_loop: + addi r4, r4,-4 /* n = n - 4 */ + lw r12, r8, r4 /* v = *(as + n) */ + bslli r9, r12, 16 /* t1 = v << 16 */ + or r9, r11, r9 /* t1 = h | t1 */ + sw r9, r5, r4 /* *(d + n) = t1 */ + bneid r4, d_wu2_loop /* while (n) loop */ + bsrli r11, r12, 16 /* h = v >> 16 (IN DELAY SLOT) */ + +d_word_done: + +d_xfer_end: +d_xfer_end_loop: + beqi r7, a_done /* while (c) */ + addi r6, r6, -1 /* s-- */ + lbui r9, r6, 0 /* t1 = *s */ + addi r5, r5, -1 /* d-- */ + sbi r9, r5, 0 /* *d = t1 */ + brid d_xfer_end_loop /* loop */ + addi r7, r7, -1 /* c-- (IN DELAY SLOT) */ + +d_done: + rtsd r15, 8 + nop + +.end memmove diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c new file mode 100644 index 0000000..5880119 --- /dev/null +++ b/arch/microblaze/lib/memcpy.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2007 John Williams + * + * Reasonably optimised generic C-code for memcpy on Microblaze + * This is generic C code to do efficient, alignment-aware memcpy. + * + * It is based on demo code originally Copyright 2001 by Intel Corp, taken from + * http://www.embedded.com/showArticle.jhtml?articleID=19205567 + * + * Attempts were made, unsuccesfully, to contact the original + * author of this code (Michael Morrow, Intel). Below is the original + * copyright notice. + * + * This software has been developed by Intel Corporation. + * Intel specifically disclaims all warranties, express or + * implied, and all liability, including consequential and + * other indirect damages, for the use of this program, including + * liability for infringement of any proprietary rights, + * and including the warranties of merchantability and fitness + * for a particular purpose. Intel does not assume any + * responsibility for and errors which may appear in this program + * not any responsibility to update it. + */ + +#include <linux/types.h> +#include <linux/stddef.h> +#include <linux/compiler.h> +#include <linux/module.h> + +#include <linux/string.h> +#include <asm/system.h> + +#ifdef __HAVE_ARCH_MEMCPY +void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) +{ + const char *src = v_src; + char *dst = v_dst; +#ifndef CONFIG_OPT_LIB_FUNCTION + /* Simple, byte oriented memcpy. */ + while (c--) + *dst++ = *src++; + + return v_dst; +#else + /* The following code tries to optimize the copy by using unsigned + * alignment. This will work fine if both source and destination are + * aligned on the same boundary. However, if they are aligned on + * different boundaries shifts will be necessary. This might result in + * bad performance on MicroBlaze systems without a barrel shifter. + */ + const uint32_t *i_src; + uint32_t *i_dst; + + if (c >= 4) { + unsigned value, buf_hold; + + /* Align the dstination to a word boundry. */ + /* This is done in an endian independant manner. */ + switch ((unsigned long)dst & 3) { + case 1: + *dst++ = *src++; + --c; + case 2: + *dst++ = *src++; + --c; + case 3: + *dst++ = *src++; + --c; + } + + i_dst = (void *)dst; + + /* Choose a copy scheme based on the source */ + /* alignment relative to dstination. */ + switch ((unsigned long)src & 3) { + case 0x0: /* Both byte offsets are aligned */ + i_src = (const void *)src; + + for (; c >= 4; c -= 4) + *i_dst++ = *i_src++; + + src = (const void *)i_src; + break; + case 0x1: /* Unaligned - Off by 1 */ + /* Word align the source */ + i_src = (const void *) ((unsigned)src & ~3); + + /* Load the holding buffer */ + buf_hold = *i_src++ << 8; + + for (; c >= 4; c -= 4) { + value = *i_src++; + *i_dst++ = buf_hold | value >> 24; + buf_hold = value << 8; + } + + /* Realign the source */ + src = (const void *)i_src; + src -= 3; + break; + case 0x2: /* Unaligned - Off by 2 */ + /* Word align the source */ + i_src = (const void *) ((unsigned)src & ~3); + + /* Load the holding buffer */ + buf_hold = *i_src++ << 16; + + for (; c >= 4; c -= 4) { + value = *i_src++; + *i_dst++ = buf_hold | value >> 16; + buf_hold = value << 16; + } + + /* Realign the source */ + src = (const void *)i_src; + src -= 2; + break; + case 0x3: /* Unaligned - Off by 3 */ + /* Word align the source */ + i_src = (const void *) ((unsigned)src & ~3); + + /* Load the holding buffer */ + buf_hold = *i_src++ << 24; + + for (; c >= 4; c -= 4) { + value = *i_src++; + *i_dst++ = buf_hold | value >> 8; + buf_hold = value << 24; + } + + /* Realign the source */ + src = (const void *)i_src; + src -= 1; + break; + } + dst = (void *)i_dst; + } + + /* Finish off any remaining bytes */ + /* simple fast copy, ... unless a cache boundry is crossed */ + switch (c) { + case 3: + *dst++ = *src++; + case 2: + *dst++ = *src++; + case 1: + *dst++ = *src++; + } + + return v_dst; +#endif +} +EXPORT_SYMBOL(memcpy); +#endif /* __HAVE_ARCH_MEMCPY */ + +void *cacheable_memcpy(void *d, const void *s, __kernel_size_t c) +{ + return memcpy(d, s, c); +} diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c new file mode 100644 index 0000000..d4e9f49 --- /dev/null +++ b/arch/microblaze/lib/memmove.c @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2007 John Williams + * + * Reasonably optimised generic C-code for memcpy on Microblaze + * This is generic C code to do efficient, alignment-aware memmove. + * + * It is based on demo code originally Copyright 2001 by Intel Corp, taken from + * http://www.embedded.com/showArticle.jhtml?articleID=19205567 + * + * Attempts were made, unsuccesfully, to contact the original + * author of this code (Michael Morrow, Intel). Below is the original + * copyright notice. + * + * This software has been developed by Intel Corporation. + * Intel specifically disclaims all warranties, express or + * implied, and all liability, including consequential and + * other indirect damages, for the use of this program, including + * liability for infringement of any proprietary rights, + * and including the warranties of merchantability and fitness + * for a particular purpose. Intel does not assume any + * responsibility for and errors which may appear in this program + * not any responsibility to update it. + */ + +#include <linux/types.h> +#include <linux/stddef.h> +#include <linux/compiler.h> +#include <linux/module.h> +#include <linux/string.h> + +#ifdef __HAVE_ARCH_MEMMOVE +void *memmove(void *v_dst, const void *v_src, __kernel_size_t c) +{ + const char *src = v_src; + char *dst = v_dst; + +#ifdef CONFIG_OPT_LIB_FUNCTION + const uint32_t *i_src; + uint32_t *i_dst; +#endif + + if (!c) + return v_dst; + + /* Use memcpy when source is higher than dest */ + if (v_dst <= v_src) + return memcpy(v_dst, v_src, c); + +#ifndef CONFIG_OPT_LIB_FUNCTION + /* copy backwards, from end to beginning */ + src += c; + dst += c; + + /* Simple, byte oriented memmove. */ + while (c--) + *--dst = *--src; + + return v_dst; +#else + /* The following code tries to optimize the copy by using unsigned + * alignment. This will work fine if both source and destination are + * aligned on the same boundary. However, if they are aligned on + * different boundaries shifts will be necessary. This might result in + * bad performance on MicroBlaze systems without a barrel shifter. + */ + /* FIXME this part needs more test */ + /* Do a descending copy - this is a bit trickier! */ + dst += c; + src += c; + + if (c >= 4) { + unsigned value, buf_hold; + + /* Align the destination to a word boundry. */ + /* This is done in an endian independant manner. */ + + switch ((unsigned long)dst & 3) { + case 3: + *--dst = *--src; + --c; + case 2: + *--dst = *--src; + --c; + case 1: + *--dst = *--src; + --c; + } + + i_dst = (void *)dst; + /* Choose a copy scheme based on the source */ + /* alignment relative to dstination. */ + switch ((unsigned long)src & 3) { + case 0x0: /* Both byte offsets are aligned */ + + i_src = (const void *)src; + + for (; c >= 4; c -= 4) + *--i_dst = *--i_src; + + src = (const void *)i_src; + break; + case 0x1: /* Unaligned - Off by 1 */ + /* Word align the source */ + i_src = (const void *) (((unsigned)src + 4) & ~3); + + /* Load the holding buffer */ + buf_hold = *--i_src >> 24; + + for (; c >= 4; c -= 4) { + value = *--i_src; + *--i_dst = buf_hold << 8 | value; + buf_hold = value >> 24; + } + + /* Realign the source */ + src = (const void *)i_src; + src += 1; + break; + case 0x2: /* Unaligned - Off by 2 */ + /* Word align the source */ + i_src = (const void *) (((unsigned)src + 4) & ~3); + + /* Load the holding buffer */ + buf_hold = *--i_src >> 16; + + for (; c >= 4; c -= 4) { + value = *--i_src; + *--i_dst = buf_hold << 16 | value; + buf_hold = value >> 16; + } + + /* Realign the source */ + src = (const void *)i_src; + src += 2; + break; + case 0x3: /* Unaligned - Off by 3 */ + /* Word align the source */ + i_src = (const void *) (((unsigned)src + 4) & ~3); + + /* Load the holding buffer */ + buf_hold = *--i_src >> 8; + + for (; c >= 4; c -= 4) { + value = *--i_src; + *--i_dst = buf_hold << 24 | value; + buf_hold = value >> 8; + } + + /* Realign the source */ + src = (const void *)i_src; + src += 3; + break; + } + dst = (void *)i_dst; + } + + /* simple fast copy, ... unless a cache boundry is crossed */ + /* Finish off any remaining bytes */ + switch (c) { + case 4: + *--dst = *--src; + case 3: + *--dst = *--src; + case 2: + *--dst = *--src; + case 1: + *--dst = *--src; + } + return v_dst; +#endif +} +EXPORT_SYMBOL(memmove); +#endif /* __HAVE_ARCH_MEMMOVE */ diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c new file mode 100644 index 0000000..941dc8f --- /dev/null +++ b/arch/microblaze/lib/memset.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2008-2009 PetaLogix + * Copyright (C) 2007 John Williams + * + * Reasonably optimised generic C-code for memset on Microblaze + * This is generic C code to do efficient, alignment-aware memcpy. + * + * It is based on demo code originally Copyright 2001 by Intel Corp, taken from + * http://www.embedded.com/showArticle.jhtml?articleID=19205567 + * + * Attempts were made, unsuccesfully, to contact the original + * author of this code (Michael Morrow, Intel). Below is the original + * copyright notice. + * + * This software has been developed by Intel Corporation. + * Intel specifically disclaims all warranties, express or + * implied, and all liability, including consequential and + * other indirect damages, for the use of this program, including + * liability for infringement of any proprietary rights, + * and including the warranties of merchantability and fitness + * for a particular purpose. Intel does not assume any + * responsibility for and errors which may appear in this program + * not any responsibility to update it. + */ + +#include <linux/types.h> +#include <linux/stddef.h> +#include <linux/compiler.h> +#include <linux/module.h> +#include <linux/string.h> + +#ifdef __HAVE_ARCH_MEMSET +void *memset(void *v_src, int c, __kernel_size_t n) +{ + + char *src = v_src; +#ifdef CONFIG_OPT_LIB_FUNCTION + uint32_t *i_src; + uint32_t w32; +#endif + /* Truncate c to 8 bits */ + c = (c & 0xFF); + +#ifdef CONFIG_OPT_LIB_FUNCTION + /* Make a repeating word out of it */ + w32 = c; + w32 |= w32 << 8; + w32 |= w32 << 16; + + if (n >= 4) { + /* Align the destination to a word boundary */ + /* This is done in an endian independant manner */ + switch ((unsigned) src & 3) { + case 1: + *src++ = c; + --n; + case 2: + *src++ = c; + --n; + case 3: + *src++ = c; + --n; + } + + i_src = (void *)src; + + /* Do as many full-word copies as we can */ + for (; n >= 4; n -= 4) + *i_src++ = w32; + + src = (void *)i_src; + } +#endif + /* Simple, byte oriented memset or the rest of count. */ + while (n--) + *src++ = c; + + return v_src; +} +EXPORT_SYMBOL(memset); +#endif /* __HAVE_ARCH_MEMSET */ diff --git a/arch/microblaze/lib/uaccess.c b/arch/microblaze/lib/uaccess.c new file mode 100644 index 0000000..8eb9df5 --- /dev/null +++ b/arch/microblaze/lib/uaccess.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/string.h> +#include <asm/uaccess.h> + +#include <asm/bug.h> + +long strnlen_user(const char __user *src, long count) +{ + return strlen(src) + 1; +} + +#define __do_strncpy_from_user(dst, src, count, res) \ + do { \ + char *tmp; \ + strncpy(dst, src, count); \ + for (tmp = dst; *tmp && count > 0; tmp++, count--) \ + ; \ + res = (tmp - dst); \ + } while (0) + +long __strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res; + __do_strncpy_from_user(dst, src, count, res); + return res; +} + +long strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + __do_strncpy_from_user(dst, src, count, res); + return res; +} diff --git a/arch/microblaze/mm/Makefile b/arch/microblaze/mm/Makefile new file mode 100644 index 0000000..bf9e447 --- /dev/null +++ b/arch/microblaze/mm/Makefile @@ -0,0 +1,5 @@ +# +# Makefile +# + +obj-y := init.o diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c new file mode 100644 index 0000000..b0c8213 --- /dev/null +++ b/arch/microblaze/mm/init.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/bootmem.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/lmb.h> +#include <linux/mm.h> /* mem_init */ +#include <linux/initrd.h> +#include <linux/pagemap.h> +#include <linux/pfn.h> +#include <linux/swap.h> + +#include <asm/page.h> +#include <asm/mmu_context.h> +#include <asm/pgalloc.h> +#include <asm/sections.h> +#include <asm/tlb.h> + +unsigned int __page_offset; +/* EXPORT_SYMBOL(__page_offset); */ + +char *klimit = _end; + +/* + * Initialize the bootmem system and give it all the memory we + * have available. + */ +unsigned int memory_start; +unsigned int memory_end; /* due to mm/nommu.c */ +unsigned int memory_size; + +/* + * paging_init() sets up the page tables - in fact we've already done this. + */ +static void __init paging_init(void) +{ + int i; + unsigned long zones_size[MAX_NR_ZONES]; + + /* + * old: we can DMA to/from any address.put all page into ZONE_DMA + * We use only ZONE_NORMAL + */ + zones_size[ZONE_NORMAL] = max_mapnr; + + /* every other zones are empty */ + for (i = 1; i < MAX_NR_ZONES; i++) + zones_size[i] = 0; + + free_area_init(zones_size); +} + +void __init setup_memory(void) +{ + int i; + unsigned long map_size; + u32 kernel_align_start, kernel_align_size; + + /* Find main memory where is the kernel */ + for (i = 0; i < lmb.memory.cnt; i++) { + memory_start = (u32) lmb.memory.region[i].base; + memory_end = (u32) lmb.memory.region[i].base + + (u32) lmb.memory.region[i].size; + if ((memory_start <= (u32)_text) && + ((u32)_text <= memory_end)) { + memory_size = memory_end - memory_start; + PAGE_OFFSET = memory_start; + printk(KERN_INFO "%s: Main mem: 0x%x-0x%x, " + "size 0x%08x\n", __func__, memory_start, + memory_end, memory_size); + break; + } + } + + if (!memory_start || !memory_end) { + panic("%s: Missing memory setting 0x%08x-0x%08x\n", + __func__, memory_start, memory_end); + } + + /* reservation of region where is the kernel */ + kernel_align_start = PAGE_DOWN((u32)_text); + /* ALIGN can be remove because _end in vmlinux.lds.S is align */ + kernel_align_size = PAGE_UP((u32)klimit) - kernel_align_start; + lmb_reserve(kernel_align_start, kernel_align_size); + printk(KERN_INFO "%s: kernel addr=0x%08x-0x%08x size=0x%08x\n", + __func__, kernel_align_start, kernel_align_start + + kernel_align_size, kernel_align_size); + + /* + * Kernel: + * start: base phys address of kernel - page align + * end: base phys address of kernel - page align + * + * min_low_pfn - the first page (mm/bootmem.c - node_boot_start) + * max_low_pfn + * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn) + * num_physpages - number of all pages + */ + + /* memory start is from the kernel end (aligned) to higher addr */ + min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */ + /* RAM is assumed contiguous */ + num_physpages = max_mapnr = memory_size >> PAGE_SHIFT; + max_pfn = max_low_pfn = memory_end >> PAGE_SHIFT; + + printk(KERN_INFO "%s: max_mapnr: %#lx\n", __func__, max_mapnr); + printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __func__, min_low_pfn); + printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __func__, max_low_pfn); + + /* + * Find an area to use for the bootmem bitmap. + * We look for the first area which is at least + * 128kB in length (128kB is enough for a bitmap + * for 4GB of memory, using 4kB pages), plus 1 page + * (in case the address isn't page-aligned). + */ + map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32)_end)), + min_low_pfn, max_low_pfn); + + lmb_reserve(PFN_UP(TOPHYS((u32)_end)) << PAGE_SHIFT, map_size); + + /* free bootmem is whole main memory */ + free_bootmem(memory_start, memory_size); + + /* reserve allocate blocks */ + for (i = 0; i < lmb.reserved.cnt; i++) { + pr_debug("reserved %d - 0x%08x-0x%08x\n", i, + (u32) lmb.reserved.region[i].base, + (u32) lmb_size_bytes(&lmb.reserved, i)); + reserve_bootmem(lmb.reserved.region[i].base, + lmb_size_bytes(&lmb.reserved, i) - 1, BOOTMEM_DEFAULT); + } + paging_init(); +} + +void free_init_pages(char *what, unsigned long begin, unsigned long end) +{ + unsigned long addr; + + for (addr = begin; addr < end; addr += PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + init_page_count(virt_to_page(addr)); + memset((void *)addr, 0xcc, PAGE_SIZE); + free_page(addr); + totalram_pages++; + } + printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); +} + +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + int pages = 0; + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(virt_to_page(start)); + init_page_count(virt_to_page(start)); + free_page(start); + totalram_pages++; + pages++; + } + printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages); +} +#endif + +void free_initmem(void) +{ + free_init_pages("unused kernel memory", + (unsigned long)(&__init_begin), + (unsigned long)(&__init_end)); +} + +/* FIXME from arch/powerpc/mm/mem.c*/ +void show_mem(void) +{ + printk(KERN_NOTICE "%s\n", __func__); +} + +void __init mem_init(void) +{ + high_memory = (void *)__va(memory_end); + /* this will put all memory onto the freelists */ + totalram_pages += free_all_bootmem(); + + printk(KERN_INFO "Memory: %luk/%luk available\n", + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), + num_physpages << (PAGE_SHIFT-10)); +} + +/* Check against bounds of physical memory */ +int ___range_ok(unsigned long addr, unsigned long size) +{ + return ((addr < memory_start) || + ((addr + size) > memory_end)); +} diff --git a/arch/microblaze/platform/Kconfig.platform b/arch/microblaze/platform/Kconfig.platform new file mode 100644 index 0000000..8e9b475 --- /dev/null +++ b/arch/microblaze/platform/Kconfig.platform @@ -0,0 +1,85 @@ +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# +# Platform selection Kconfig menu for MicroBlaze targets +# + +menu "Platform options" +choice + prompt "Platform" + default PLATFORM_MICROBLAZE_AUTO + help + Choose which hardware board/platform you are targeting. + +config PLATFORM_GENERIC + bool "Generic" + help + Choose this option for the Generic platform. + +endchoice + +config SELFMOD + bool "Use self modified code for intc/timer" + depends on EXPERIMENTAL && NO_MMU + default n + help + This choice enables self-modified code for interrupt controller + and timer. + +config SELFMOD_INTC + bool "Use self modified code for intc" + depends on SELFMOD + default y + help + This choice enables self-modified code for interrupt controller. + +config SELFMOD_TIMER + bool "Use self modified code for timer" + depends on SELFMOD + default y + help + This choice enables self-modified code for timer. + +config OPT_LIB_FUNCTION + bool "Optimalized lib function" + default y + help + Allows turn on optimalized library function (memcpy and memmove). + They are optimized by using word alignment. This will work + fine if both source and destination are aligned on the same + boundary. However, if they are aligned on different boundaries + shifts will be necessary. This might result in bad performance + on MicroBlaze systems without a barrel shifter. + +config OPT_LIB_ASM + bool "Optimalized lib function ASM" + depends on OPT_LIB_FUNCTION + default n + help + Allows turn on optimalized library function (memcpy and memmove). + Function are written in asm code. + +# This is still a bit broken - disabling for now JW 20070504 +config ALLOW_EDIT_AUTO + bool "Permit Display/edit of Kconfig.auto platform settings" + default n + help + Allows the editing of auto-generated platform settings from + the Kconfig.auto file. Obviously this does not change the + underlying hardware, so be very careful if you go editing + these settings. + + Also, if you enable this, and edit various Kconfig.auto + settings, YOUR CHANGES WILL BE LOST if you then disable it + again. You have been warned! + + If unsure, say no. + +comment "Automatic platform settings from Kconfig.auto" + depends on ALLOW_EDIT_AUTO + +if PLATFORM_GENERIC=y + source "arch/microblaze/platform/generic/Kconfig.auto" +endif + +endmenu diff --git a/arch/microblaze/platform/Makefile b/arch/microblaze/platform/Makefile new file mode 100644 index 0000000..ea1b75c --- /dev/null +++ b/arch/microblaze/platform/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for arch/microblaze/platform directory +# +#obj-$(CONFIG_PLATFORM_GENERIC) += generic/ + +obj-y += platform.o diff --git a/arch/microblaze/platform/generic/Kconfig.auto b/arch/microblaze/platform/generic/Kconfig.auto new file mode 100644 index 0000000..fbca22d --- /dev/null +++ b/arch/microblaze/platform/generic/Kconfig.auto @@ -0,0 +1,62 @@ +# +# (C) Copyright 2007 Michal Simek +# +# Michal SIMEK <monstr@monstr.eu> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# Definitions for MICROBLAZE0 +comment "Definitions for MICROBLAZE0" + depends on ALLOW_EDIT_AUTO + +config KERNEL_BASE_ADDR + hex "Physical address where Linux Kernel is" + default "0x90000000" + help + BASE Address for kernel + +config XILINX_MICROBLAZE0_FAMILY + string "Targetted FPGA family" if ALLOW_EDIT_AUTO + default "virtex5" + +config XILINX_MICROBLAZE0_USE_MSR_INSTR + int "USE_MSR_INSTR range (0:1)" if ALLOW_EDIT_AUTO + default 1 + +config XILINX_MICROBLAZE0_USE_PCMP_INSTR + int "USE_PCMP_INSTR range (0:1)" if ALLOW_EDIT_AUTO + default 1 + +config XILINX_MICROBLAZE0_USE_BARREL + int "USE_BARREL range (0:1)" if ALLOW_EDIT_AUTO + default 1 + +config XILINX_MICROBLAZE0_USE_DIV + int "USE_DIV range (0:1)" if ALLOW_EDIT_AUTO + default 1 + +config XILINX_MICROBLAZE0_USE_HW_MUL + int "USE_HW_MUL values (0=NONE, 1=MUL32, 2=MUL64)" if ALLOW_EDIT_AUTO + default 2 + +config XILINX_MICROBLAZE0_USE_FPU + int "USE_FPU values (0=NONE, 1=BASIC, 2=EXTENDED)" if ALLOW_EDIT_AUTO + default 2 + +config XILINX_MICROBLAZE0_HW_VER + string "Core version number" if ALLOW_EDIT_AUTO + default 7.10.d diff --git a/arch/microblaze/platform/generic/Makefile b/arch/microblaze/platform/generic/Makefile new file mode 100644 index 0000000..9a8b1bd --- /dev/null +++ b/arch/microblaze/platform/generic/Makefile @@ -0,0 +1,3 @@ +# +# Empty Makefile to keep make clean happy +# diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts new file mode 100644 index 0000000..29993f6 --- /dev/null +++ b/arch/microblaze/platform/generic/system.dts @@ -0,0 +1,332 @@ +/* + * Device Tree Generator version: 1.1 + * + * (C) Copyright 2007-2008 Xilinx, Inc. + * (C) Copyright 2007-2009 Michal Simek + * + * Michal SIMEK <monstr@monstr.eu> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * CAUTION: This file is automatically generated by libgen. + * Version: Xilinx EDK 10.1.03 EDK_K_SP3.6 + * + * XPS project directory: Xilinx-ML505-ll_temac-sgdma-MMU-FDT-edk101 + */ + +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,microblaze"; + model = "testing"; + DDR2_SDRAM: memory@90000000 { + device_type = "memory"; + reg = < 0x90000000 0x10000000 >; + } ; + chosen { + bootargs = "console=ttyUL0,115200 highres=on"; + linux,stdout-path = "/plb@0/serial@84000000"; + } ; + cpus { + #address-cells = <1>; + #cpus = <0x1>; + #size-cells = <0>; + microblaze_0: cpu@0 { + clock-frequency = <125000000>; + compatible = "xlnx,microblaze-7.10.d"; + d-cache-baseaddr = <0x90000000>; + d-cache-highaddr = <0x9fffffff>; + d-cache-line-size = <0x10>; + d-cache-size = <0x2000>; + device_type = "cpu"; + i-cache-baseaddr = <0x90000000>; + i-cache-highaddr = <0x9fffffff>; + i-cache-line-size = <0x10>; + i-cache-size = <0x2000>; + model = "microblaze,7.10.d"; + reg = <0>; + timebase-frequency = <125000000>; + xlnx,addr-tag-bits = <0xf>; + xlnx,allow-dcache-wr = <0x1>; + xlnx,allow-icache-wr = <0x1>; + xlnx,area-optimized = <0x0>; + xlnx,cache-byte-size = <0x2000>; + xlnx,d-lmb = <0x1>; + xlnx,d-opb = <0x0>; + xlnx,d-plb = <0x1>; + xlnx,data-size = <0x20>; + xlnx,dcache-addr-tag = <0xf>; + xlnx,dcache-always-used = <0x1>; + xlnx,dcache-byte-size = <0x2000>; + xlnx,dcache-line-len = <0x4>; + xlnx,dcache-use-fsl = <0x1>; + xlnx,debug-enabled = <0x1>; + xlnx,div-zero-exception = <0x1>; + xlnx,dopb-bus-exception = <0x0>; + xlnx,dynamic-bus-sizing = <0x1>; + xlnx,edge-is-positive = <0x1>; + xlnx,family = "virtex5"; + xlnx,fpu-exception = <0x1>; + xlnx,fsl-data-size = <0x20>; + xlnx,fsl-exception = <0x0>; + xlnx,fsl-links = <0x0>; + xlnx,i-lmb = <0x1>; + xlnx,i-opb = <0x0>; + xlnx,i-plb = <0x1>; + xlnx,icache-always-used = <0x1>; + xlnx,icache-line-len = <0x4>; + xlnx,icache-use-fsl = <0x1>; + xlnx,ill-opcode-exception = <0x1>; + xlnx,instance = "microblaze_0"; + xlnx,interconnect = <0x1>; + xlnx,interrupt-is-edge = <0x0>; + xlnx,iopb-bus-exception = <0x0>; + xlnx,mmu-dtlb-size = <0x4>; + xlnx,mmu-itlb-size = <0x2>; + xlnx,mmu-tlb-access = <0x3>; + xlnx,mmu-zones = <0x10>; + xlnx,number-of-pc-brk = <0x1>; + xlnx,number-of-rd-addr-brk = <0x0>; + xlnx,number-of-wr-addr-brk = <0x0>; + xlnx,opcode-0x0-illegal = <0x1>; + xlnx,pvr = <0x2>; + xlnx,pvr-user1 = <0x0>; + xlnx,pvr-user2 = <0x0>; + xlnx,reset-msr = <0x0>; + xlnx,sco = <0x0>; + xlnx,unaligned-exceptions = <0x1>; + xlnx,use-barrel = <0x1>; + xlnx,use-dcache = <0x1>; + xlnx,use-div = <0x1>; + xlnx,use-ext-brk = <0x1>; + xlnx,use-ext-nm-brk = <0x1>; + xlnx,use-extended-fsl-instr = <0x0>; + xlnx,use-fpu = <0x2>; + xlnx,use-hw-mul = <0x2>; + xlnx,use-icache = <0x1>; + xlnx,use-interrupt = <0x1>; + xlnx,use-mmu = <0x3>; + xlnx,use-msr-instr = <0x1>; + xlnx,use-pcmp-instr = <0x1>; + } ; + } ; + mb_plb: plb@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,plb-v46-1.03.a", "simple-bus"; + ranges ; + FLASH: flash@a0000000 { + bank-width = <2>; + compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash"; + reg = < 0xa0000000 0x2000000 >; + xlnx,family = "virtex5"; + xlnx,include-datawidth-matching-0 = <0x1>; + xlnx,include-datawidth-matching-1 = <0x0>; + xlnx,include-datawidth-matching-2 = <0x0>; + xlnx,include-datawidth-matching-3 = <0x0>; + xlnx,include-negedge-ioregs = <0x0>; + xlnx,include-plb-ipif = <0x1>; + xlnx,include-wrbuf = <0x1>; + xlnx,max-mem-width = <0x10>; + xlnx,mch-native-dwidth = <0x20>; + xlnx,mch-plb-clk-period-ps = <0x1f40>; + xlnx,mch-splb-awidth = <0x20>; + xlnx,mch0-accessbuf-depth = <0x10>; + xlnx,mch0-protocol = <0x0>; + xlnx,mch0-rddatabuf-depth = <0x10>; + xlnx,mch1-accessbuf-depth = <0x10>; + xlnx,mch1-protocol = <0x0>; + xlnx,mch1-rddatabuf-depth = <0x10>; + xlnx,mch2-accessbuf-depth = <0x10>; + xlnx,mch2-protocol = <0x0>; + xlnx,mch2-rddatabuf-depth = <0x10>; + xlnx,mch3-accessbuf-depth = <0x10>; + xlnx,mch3-protocol = <0x0>; + xlnx,mch3-rddatabuf-depth = <0x10>; + xlnx,mem0-width = <0x10>; + xlnx,mem1-width = <0x20>; + xlnx,mem2-width = <0x20>; + xlnx,mem3-width = <0x20>; + xlnx,num-banks-mem = <0x1>; + xlnx,num-channels = <0x0>; + xlnx,priority-mode = <0x0>; + xlnx,synch-mem-0 = <0x0>; + xlnx,synch-mem-1 = <0x0>; + xlnx,synch-mem-2 = <0x0>; + xlnx,synch-mem-3 = <0x0>; + xlnx,synch-pipedelay-0 = <0x2>; + xlnx,synch-pipedelay-1 = <0x2>; + xlnx,synch-pipedelay-2 = <0x2>; + xlnx,synch-pipedelay-3 = <0x2>; + xlnx,tavdv-ps-mem-0 = <0x1adb0>; + xlnx,tavdv-ps-mem-1 = <0x3a98>; + xlnx,tavdv-ps-mem-2 = <0x3a98>; + xlnx,tavdv-ps-mem-3 = <0x3a98>; + xlnx,tcedv-ps-mem-0 = <0x1adb0>; + xlnx,tcedv-ps-mem-1 = <0x3a98>; + xlnx,tcedv-ps-mem-2 = <0x3a98>; + xlnx,tcedv-ps-mem-3 = <0x3a98>; + xlnx,thzce-ps-mem-0 = <0x88b8>; + xlnx,thzce-ps-mem-1 = <0x1b58>; + xlnx,thzce-ps-mem-2 = <0x1b58>; + xlnx,thzce-ps-mem-3 = <0x1b58>; + xlnx,thzoe-ps-mem-0 = <0x1b58>; + xlnx,thzoe-ps-mem-1 = <0x1b58>; + xlnx,thzoe-ps-mem-2 = <0x1b58>; + xlnx,thzoe-ps-mem-3 = <0x1b58>; + xlnx,tlzwe-ps-mem-0 = <0x88b8>; + xlnx,tlzwe-ps-mem-1 = <0x0>; + xlnx,tlzwe-ps-mem-2 = <0x0>; + xlnx,tlzwe-ps-mem-3 = <0x0>; + xlnx,twc-ps-mem-0 = <0x2af8>; + xlnx,twc-ps-mem-1 = <0x3a98>; + xlnx,twc-ps-mem-2 = <0x3a98>; + xlnx,twc-ps-mem-3 = <0x3a98>; + xlnx,twp-ps-mem-0 = <0x11170>; + xlnx,twp-ps-mem-1 = <0x2ee0>; + xlnx,twp-ps-mem-2 = <0x2ee0>; + xlnx,twp-ps-mem-3 = <0x2ee0>; + xlnx,xcl0-linesize = <0x4>; + xlnx,xcl0-writexfer = <0x1>; + xlnx,xcl1-linesize = <0x4>; + xlnx,xcl1-writexfer = <0x1>; + xlnx,xcl2-linesize = <0x4>; + xlnx,xcl2-writexfer = <0x1>; + xlnx,xcl3-linesize = <0x4>; + xlnx,xcl3-writexfer = <0x1>; + } ; + Hard_Ethernet_MAC: xps-ll-temac@81c00000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,compound"; + ethernet@81c00000 { + compatible = "xlnx,xps-ll-temac-1.01.b"; + device_type = "network"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 5 2 >; + llink-connected = <&PIM3>; + local-mac-address = [ 02 00 00 00 00 00 ]; + reg = < 0x81c00000 0x40 >; + xlnx,bus2core-clk-ratio = <0x1>; + xlnx,phy-type = <0x1>; + xlnx,phyaddr = <0x1>; + xlnx,rxcsum = <0x0>; + xlnx,rxfifo = <0x1000>; + xlnx,temac-type = <0x0>; + xlnx,txcsum = <0x0>; + xlnx,txfifo = <0x1000>; + } ; + } ; + IIC_EEPROM: i2c@81600000 { + compatible = "xlnx,xps-iic-2.00.a"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 6 2 >; + reg = < 0x81600000 0x10000 >; + xlnx,clk-freq = <0x7735940>; + xlnx,family = "virtex5"; + xlnx,gpo-width = <0x1>; + xlnx,iic-freq = <0x186a0>; + xlnx,scl-inertial-delay = <0x0>; + xlnx,sda-inertial-delay = <0x0>; + xlnx,ten-bit-adr = <0x0>; + } ; + LEDs_8Bit: gpio@81400000 { + compatible = "xlnx,xps-gpio-1.00.a"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 7 2 >; + reg = < 0x81400000 0x10000 >; + xlnx,all-inputs = <0x0>; + xlnx,all-inputs-2 = <0x0>; + xlnx,dout-default = <0x0>; + xlnx,dout-default-2 = <0x0>; + xlnx,family = "virtex5"; + xlnx,gpio-width = <0x8>; + xlnx,interrupt-present = <0x1>; + xlnx,is-bidir = <0x1>; + xlnx,is-bidir-2 = <0x1>; + xlnx,is-dual = <0x0>; + xlnx,tri-default = <0xffffffff>; + xlnx,tri-default-2 = <0xffffffff>; + } ; + RS232_Uart_1: serial@84000000 { + clock-frequency = <125000000>; + compatible = "xlnx,xps-uartlite-1.00.a"; + current-speed = <115200>; + device_type = "serial"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 8 0 >; + port-number = <0>; + reg = < 0x84000000 0x10000 >; + xlnx,baudrate = <0x1c200>; + xlnx,data-bits = <0x8>; + xlnx,family = "virtex5"; + xlnx,odd-parity = <0x0>; + xlnx,use-parity = <0x0>; + } ; + SysACE_CompactFlash: sysace@83600000 { + compatible = "xlnx,xps-sysace-1.00.a"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 4 2 >; + reg = < 0x83600000 0x10000 >; + xlnx,family = "virtex5"; + xlnx,mem-width = <0x10>; + } ; + debug_module: debug@84400000 { + compatible = "xlnx,mdm-1.00.d"; + reg = < 0x84400000 0x10000 >; + xlnx,family = "virtex5"; + xlnx,interconnect = <0x1>; + xlnx,jtag-chain = <0x2>; + xlnx,mb-dbg-ports = <0x1>; + xlnx,uart-width = <0x8>; + xlnx,use-uart = <0x1>; + xlnx,write-fsl-ports = <0x0>; + } ; + mpmc@90000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,mpmc-4.02.a"; + PIM3: sdma@84600180 { + compatible = "xlnx,ll-dma-1.00.a"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 2 2 1 2 >; + reg = < 0x84600180 0x80 >; + } ; + } ; + xps_intc_0: interrupt-controller@81800000 { + #interrupt-cells = <0x2>; + compatible = "xlnx,xps-intc-1.00.a"; + interrupt-controller ; + reg = < 0x81800000 0x10000 >; + xlnx,kind-of-intr = <0x100>; + xlnx,num-intr-inputs = <0x9>; + } ; + xps_timer_1: timer@83c00000 { + compatible = "xlnx,xps-timer-1.00.a"; + interrupt-parent = <&xps_intc_0>; + interrupts = < 3 2 >; + reg = < 0x83c00000 0x10000 >; + xlnx,count-width = <0x20>; + xlnx,family = "virtex5"; + xlnx,gen0-assert = <0x1>; + xlnx,gen1-assert = <0x1>; + xlnx,one-timer-only = <0x0>; + xlnx,trig0-assert = <0x1>; + xlnx,trig1-assert = <0x1>; + } ; + } ; +} ; diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c new file mode 100644 index 0000000..56e0234 --- /dev/null +++ b/arch/microblaze/platform/platform.c @@ -0,0 +1,31 @@ +/* + * Copyright 2008 Michal Simek <monstr@monstr.eu> + * + * based on virtex.c file + * + * Copyright 2007 Secret Lab Technologies Ltd. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include <linux/init.h> +#include <linux/of_platform.h> +#include <asm/prom.h> + +static struct of_device_id xilinx_of_bus_ids[] __initdata = { + { .compatible = "simple-bus", }, + { .compatible = "xlnx,plb-v46-1.00.a", }, + { .compatible = "xlnx,opb-v20-1.10.c", }, + { .compatible = "xlnx,opb-v20-1.10.b", }, + { .compatible = "xlnx,compound", }, + {} +}; + +static int __init microblaze_device_probe(void) +{ + of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL); + return 0; +} +device_initcall(microblaze_device_probe); diff --git a/arch/mips/include/asm/mach-rc32434/gpio.h b/arch/mips/include/asm/mach-rc32434/gpio.h index 3cb50d1..12ee8d5 100644 --- a/arch/mips/include/asm/mach-rc32434/gpio.h +++ b/arch/mips/include/asm/mach-rc32434/gpio.h @@ -80,6 +80,9 @@ struct rb532_gpio_reg { /* Compact Flash GPIO pin */ #define CF_GPIO_NUM 13 +/* S1 button GPIO (shared with UART0_SIN) */ +#define GPIO_BTN_S1 1 + extern void rb532_gpio_set_ilevel(int bit, unsigned gpio); extern void rb532_gpio_set_istat(int bit, unsigned gpio); extern void rb532_gpio_set_func(unsigned gpio); diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 4a5f05b..9f40e1f 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -200,26 +200,9 @@ static struct platform_device rb532_led = { .id = -1, }; -static struct gpio_keys_button rb532_gpio_btn[] = { - { - .gpio = 1, - .code = BTN_0, - .desc = "S1", - .active_low = 1, - } -}; - -static struct gpio_keys_platform_data rb532_gpio_btn_data = { - .buttons = rb532_gpio_btn, - .nbuttons = ARRAY_SIZE(rb532_gpio_btn), -}; - static struct platform_device rb532_button = { - .name = "gpio-keys", + .name = "rb532-button", .id = -1, - .dev = { - .platform_data = &rb532_gpio_btn_data, - } }; static struct resource rb532_wdt_res[] = { diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 41d1682..3559267 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -370,5 +370,3 @@ source "security/Kconfig" source "crypto/Kconfig" source "lib/Kconfig" - -source "arch/mn10300/oprofile/Kconfig" diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile index 6673a28..dd0c8ff 100644 --- a/arch/mn10300/Makefile +++ b/arch/mn10300/Makefile @@ -94,42 +94,8 @@ ifdef CONFIG_DEBUG_INFO KBUILD_AFLAGS += -Wa,--gdwarf2 endif -################################################################################################### # -# juggle some symlinks in the MN10300 asm include dir +# include the appropriate processor- and unit-specific headers # -# Update machine proc and unit symlinks if something which affects -# them changed. We use .proc / .unit to indicate when they were -# updated last, otherwise make uses the target directory mtime. -# -################################################################################################### - -# processor specific definitions -include/asm-mn10300/.proc: $(wildcard include/config/proc/*.h) include/config/auto.conf - @echo ' SYMLINK include/asm-mn10300/proc -> include/asm-mn10300/proc-$(PROCESSOR)' -ifneq ($(KBUILD_SRC),) - $(Q)mkdir -p include/asm-mn10300 - $(Q)ln -fsn $(srctree)/include/asm-mn10300/proc-$(PROCESSOR) include/asm-mn10300/proc -else - $(Q)ln -fsn proc-$(PROCESSOR) include/asm-mn10300/proc -endif - @touch $@ - -CLEAN_FILES += include/asm-mn10300/proc include/asm-mn10300/.proc - -prepare: include/asm-mn10300/.proc - -# unit specific definitions -include/asm-mn10300/.unit: $(wildcard include/config/unit/*.h) include/config/auto.conf - @echo ' SYMLINK include/asm-mn10300/unit -> include/asm-mn10300/unit-$(UNIT)' -ifneq ($(KBUILD_SRC),) - $(Q)mkdir -p include/asm-mn10300 - $(Q)ln -fsn $(srctree)/include/asm-mn10300/unit-$(UNIT) include/asm-mn10300/unit -else - $(Q)ln -fsn unit-$(UNIT) include/asm-mn10300/unit -endif - @touch $@ - -CLEAN_FILES += include/asm-mn10300/unit include/asm-mn10300/.unit - -prepare: include/asm-mn10300/.unit +KBUILD_CPPFLAGS += -I$(srctree)/arch/mn10300/proc-$(PROCESSOR)/include +KBUILD_CPPFLAGS += -I$(srctree)/arch/mn10300/unit-$(UNIT)/include diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild new file mode 100644 index 0000000..c68e168 --- /dev/null +++ b/arch/mn10300/include/asm/Kbuild @@ -0,0 +1 @@ +include include/asm-generic/Kbuild.asm diff --git a/arch/mn10300/include/asm/atomic.h b/arch/mn10300/include/asm/atomic.h new file mode 100644 index 0000000..bc06482 --- /dev/null +++ b/arch/mn10300/include/asm/atomic.h @@ -0,0 +1,157 @@ +/* MN10300 Atomic counter operations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_ATOMIC_H +#define _ASM_ATOMIC_H + +#ifdef CONFIG_SMP +#error not SMP safe +#endif + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +#define ATOMIC_INIT(i) { (i) } + +#ifdef __KERNEL__ + +/** + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define atomic_read(v) ((v)->counter) + +/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define atomic_set(v, i) (((v)->counter) = (i)) + +#include <asm/system.h> + +/** + * atomic_add_return - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v and returns the result + * Note that the guaranteed useful range of an atomic_t is only 24 bits. + */ +static inline int atomic_add_return(int i, atomic_t *v) +{ + unsigned long flags; + int temp; + + local_irq_save(flags); + temp = v->counter; + temp += i; + v->counter = temp; + local_irq_restore(flags); + + return temp; +} + +/** + * atomic_sub_return - subtract integer from atomic variable + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v and returns the result + * Note that the guaranteed useful range of an atomic_t is only 24 bits. + */ +static inline int atomic_sub_return(int i, atomic_t *v) +{ + unsigned long flags; + int temp; + + local_irq_save(flags); + temp = v->counter; + temp -= i; + v->counter = temp; + local_irq_restore(flags); + + return temp; +} + +static inline int atomic_add_negative(int i, atomic_t *v) +{ + return atomic_add_return(i, v) < 0; +} + +static inline void atomic_add(int i, atomic_t *v) +{ + atomic_add_return(i, v); +} + +static inline void atomic_sub(int i, atomic_t *v) +{ + atomic_sub_return(i, v); +} + +static inline void atomic_inc(atomic_t *v) +{ + atomic_add_return(1, v); +} + +static inline void atomic_dec(atomic_t *v) +{ + atomic_sub_return(1, v); +} + +#define atomic_dec_return(v) atomic_sub_return(1, (v)) +#define atomic_inc_return(v) atomic_add_return(1, (v)) + +#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) +#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) + +#define atomic_add_unless(v, a, u) \ +({ \ + int c, old; \ + c = atomic_read(v); \ + while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ + c = old; \ + c != (u); \ +}) + +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long flags; + + mask = ~mask; + local_irq_save(flags); + *addr &= mask; + local_irq_restore(flags); +} + +#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v))) +#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) + +/* Atomic operations are already serializing on MN10300??? */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#include <asm-generic/atomic.h> + +#endif /* __KERNEL__ */ +#endif /* _ASM_ATOMIC_H */ diff --git a/arch/mn10300/include/asm/auxvec.h b/arch/mn10300/include/asm/auxvec.h new file mode 100644 index 0000000..4fdb60b --- /dev/null +++ b/arch/mn10300/include/asm/auxvec.h @@ -0,0 +1,4 @@ +#ifndef _ASM_AUXVEC_H +#define _ASM_AUXVEC_H + +#endif diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h new file mode 100644 index 0000000..0b610f4 --- /dev/null +++ b/arch/mn10300/include/asm/bitops.h @@ -0,0 +1,240 @@ +/* MN10300 bit operations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + * + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ +#ifndef __ASM_BITOPS_H +#define __ASM_BITOPS_H + +#include <asm/cpu-regs.h> + +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +/* + * set bit + */ +#define __set_bit(nr, addr) \ +({ \ + volatile unsigned char *_a = (unsigned char *)(addr); \ + const unsigned shift = (nr) & 7; \ + _a += (nr) >> 3; \ + \ + asm volatile("bset %2,(%1) # set_bit reg" \ + : "=m"(*_a) \ + : "a"(_a), "d"(1 << shift), "m"(*_a) \ + : "memory", "cc"); \ +}) + +#define set_bit(nr, addr) __set_bit((nr), (addr)) + +/* + * clear bit + */ +#define ___clear_bit(nr, addr) \ +({ \ + volatile unsigned char *_a = (unsigned char *)(addr); \ + const unsigned shift = (nr) & 7; \ + _a += (nr) >> 3; \ + \ + asm volatile("bclr %2,(%1) # clear_bit reg" \ + : "=m"(*_a) \ + : "a"(_a), "d"(1 << shift), "m"(*_a) \ + : "memory", "cc"); \ +}) + +#define clear_bit(nr, addr) ___clear_bit((nr), (addr)) + + +static inline void __clear_bit(int nr, volatile void *addr) +{ + unsigned int *a = (unsigned int *) addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a &= ~mask; +} + +/* + * test bit + */ +static inline int test_bit(int nr, const volatile void *addr) +{ + return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31)); +} + +/* + * change bit + */ +static inline void __change_bit(int nr, volatile void *addr) +{ + int mask; + unsigned int *a = (unsigned int *) addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a ^= mask; +} + +extern void change_bit(int nr, volatile void *addr); + +/* + * test and set bit + */ +#define __test_and_set_bit(nr,addr) \ +({ \ + volatile unsigned char *_a = (unsigned char *)(addr); \ + const unsigned shift = (nr) & 7; \ + unsigned epsw; \ + _a += (nr) >> 3; \ + \ + asm volatile("bset %3,(%2) # test_set_bit reg\n" \ + "mov epsw,%1" \ + : "=m"(*_a), "=d"(epsw) \ + : "a"(_a), "d"(1 << shift), "m"(*_a) \ + : "memory", "cc"); \ + \ + !(epsw & EPSW_FLAG_Z); \ +}) + +#define test_and_set_bit(nr, addr) __test_and_set_bit((nr), (addr)) + +/* + * test and clear bit + */ +#define __test_and_clear_bit(nr, addr) \ +({ \ + volatile unsigned char *_a = (unsigned char *)(addr); \ + const unsigned shift = (nr) & 7; \ + unsigned epsw; \ + _a += (nr) >> 3; \ + \ + asm volatile("bclr %3,(%2) # test_clear_bit reg\n" \ + "mov epsw,%1" \ + : "=m"(*_a), "=d"(epsw) \ + : "a"(_a), "d"(1 << shift), "m"(*_a) \ + : "memory", "cc"); \ + \ + !(epsw & EPSW_FLAG_Z); \ +}) + +#define test_and_clear_bit(nr, addr) __test_and_clear_bit((nr), (addr)) + +/* + * test and change bit + */ +static inline int __test_and_change_bit(int nr, volatile void *addr) +{ + int mask, retval; + unsigned int *a = (unsigned int *)addr; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + retval = (mask & *a) != 0; + *a ^= mask; + + return retval; +} + +extern int test_and_change_bit(int nr, volatile void *addr); + +#include <asm-generic/bitops/lock.h> + +#ifdef __KERNEL__ + +/** + * __ffs - find first bit set + * @x: the word to search + * + * - return 31..0 to indicate bit 31..0 most least significant bit set + * - if no bits are set in x, the result is undefined + */ +static inline __attribute__((const)) +unsigned long __ffs(unsigned long x) +{ + int bit; + asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(x & -x)); + return bit; +} + +/* + * special slimline version of fls() for calculating ilog2_u32() + * - note: no protection against n == 0 + */ +static inline __attribute__((const)) +int __ilog2_u32(u32 n) +{ + int bit; + asm("bsch %2,%0" : "=r"(bit) : "0"(0), "r"(n)); + return bit; +} + +/** + * fls - find last bit set + * @x: the word to search + * + * This is defined the same way as ffs: + * - return 32..1 to indicate bit 31..0 most significant bit set + * - return 0 to indicate no bits set + */ +static inline __attribute__((const)) +int fls(int x) +{ + return (x != 0) ? __ilog2_u32(x) + 1 : 0; +} + +/** + * __fls - find last (most-significant) set bit in a long word + * @word: the word to search + * + * Undefined if no set bit exists, so code should check against 0 first. + */ +static inline unsigned long __fls(unsigned long word) +{ + return __ilog2_u32(word); +} + +/** + * ffs - find first bit set + * @x: the word to search + * + * - return 32..1 to indicate bit 31..0 most least significant bit set + * - return 0 to indicate no bits set + */ +static inline __attribute__((const)) +int ffs(int x) +{ + /* Note: (x & -x) gives us a mask that is the least significant + * (rightmost) 1-bit of the value in x. + */ + return fls(x & -x); +} + +#include <asm-generic/bitops/ffz.h> +#include <asm-generic/bitops/fls64.h> +#include <asm-generic/bitops/find.h> +#include <asm-generic/bitops/sched.h> +#include <asm-generic/bitops/hweight.h> + +#define ext2_set_bit_atomic(lock, nr, addr) \ + test_and_set_bit((nr) ^ 0x18, (addr)) +#define ext2_clear_bit_atomic(lock, nr, addr) \ + test_and_clear_bit((nr) ^ 0x18, (addr)) + +#include <asm-generic/bitops/ext2-non-atomic.h> +#include <asm-generic/bitops/minix-le.h> + +#endif /* __KERNEL__ */ +#endif /* __ASM_BITOPS_H */ diff --git a/arch/mn10300/include/asm/bug.h b/arch/mn10300/include/asm/bug.h new file mode 100644 index 0000000..4fcf338 --- /dev/null +++ b/arch/mn10300/include/asm/bug.h @@ -0,0 +1,35 @@ +/* MN10300 Kernel bug reporting + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_BUG_H +#define _ASM_BUG_H + +/* + * Tell the user there is some problem. + */ +#define _debug_bug_trap() \ +do { \ + asm volatile( \ + " syscall 15 \n" \ + "0: \n" \ + " .section __bug_table,\"a\" \n" \ + " .long 0b,%0,%1 \n" \ + " .previous \n" \ + : \ + : "i"(__FILE__), "i"(__LINE__) \ + ); \ +} while (0) + +#define BUG() _debug_bug_trap() + +#define HAVE_ARCH_BUG +#include <asm-generic/bug.h> + +#endif /* _ASM_BUG_H */ diff --git a/arch/mn10300/include/asm/bugs.h b/arch/mn10300/include/asm/bugs.h new file mode 100644 index 0000000..31c8bc5 --- /dev/null +++ b/arch/mn10300/include/asm/bugs.h @@ -0,0 +1,20 @@ +/* MN10300 Checks for architecture-dependent bugs + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_BUGS_H +#define _ASM_BUGS_H + +#include <asm/processor.h> + +static inline void __init check_bugs(void) +{ +} + +#endif /* _ASM_BUGS_H */ diff --git a/arch/mn10300/include/asm/busctl-regs.h b/arch/mn10300/include/asm/busctl-regs.h new file mode 100644 index 0000000..1632aef --- /dev/null +++ b/arch/mn10300/include/asm/busctl-regs.h @@ -0,0 +1,151 @@ +/* AM33v2 on-board bus controller registers + * + * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_BUSCTL_REGS_H +#define _ASM_BUSCTL_REGS_H + +#include <asm/cpu-regs.h> + +#ifdef __KERNEL__ + +/* bus controller registers */ +#define BCCR __SYSREG(0xc0002000, u32) /* bus controller control reg */ +#define BCCR_B0AD 0x00000003 /* block 0 (80000000-83ffffff) bus allocation */ +#define BCCR_B1AD 0x0000000c /* block 1 (84000000-87ffffff) bus allocation */ +#define BCCR_B2AD 0x00000030 /* block 2 (88000000-8bffffff) bus allocation */ +#define BCCR_B3AD 0x000000c0 /* block 3 (8c000000-8fffffff) bus allocation */ +#define BCCR_B4AD 0x00000300 /* block 4 (90000000-93ffffff) bus allocation */ +#define BCCR_B5AD 0x00000c00 /* block 5 (94000000-97ffffff) bus allocation */ +#define BCCR_B6AD 0x00003000 /* block 6 (98000000-9bffffff) bus allocation */ +#define BCCR_B7AD 0x0000c000 /* block 7 (9c000000-9fffffff) bus allocation */ +#define BCCR_BxAD_EXBUS 0x0 /* - direct to system bus controller */ +#define BCCR_BxAD_OPEXBUS 0x1 /* - direct to memory bus controller */ +#define BCCR_BxAD_OCMBUS 0x2 /* - direct to on chip memory */ +#define BCCR_API 0x00070000 /* bus arbitration priority */ +#define BCCR_API_DMACICD 0x00000000 /* - DMA > CI > CD */ +#define BCCR_API_DMACDCI 0x00010000 /* - DMA > CD > CI */ +#define BCCR_API_CICDDMA 0x00020000 /* - CI > CD > DMA */ +#define BCCR_API_CDCIDMA 0x00030000 /* - CD > CI > DMA */ +#define BCCR_API_ROUNDROBIN 0x00040000 /* - round robin */ +#define BCCR_BEPRI_DMACICD 0x00c00000 /* bus error address priority */ +#define BCCR_BEPRI_DMACDCI 0x00000000 /* - DMA > CI > CD */ +#define BCCR_BEPRI_CICDDMA 0x00400000 /* - DMA > CD > CI */ +#define BCCR_BEPRI_CDCIDMA 0x00800000 /* - CI > CD > DMA */ +#define BCCR_BEPRI 0x00c00000 /* - CD > CI > DMA */ +#define BCCR_TMON 0x03000000 /* timeout value settings */ +#define BCCR_TMON_16IOCLK 0x00000000 /* - 16 IOCLK cycles */ +#define BCCR_TMON_256IOCLK 0x01000000 /* - 256 IOCLK cycles */ +#define BCCR_TMON_4096IOCLK 0x02000000 /* - 4096 IOCLK cycles */ +#define BCCR_TMON_65536IOCLK 0x03000000 /* - 65536 IOCLK cycles */ +#define BCCR_TMOE 0x10000000 /* timeout detection enable */ + +#define BCBERR __SYSREG(0xc0002010, u32) /* bus error source reg */ +#define BCBERR_BESB 0x0000001f /* erroneous access destination space */ +#define BCBERR_BESB_MON 0x00000001 /* - monitor space */ +#define BCBERR_BESB_IO 0x00000002 /* - IO bus */ +#define BCBERR_BESB_EX 0x00000004 /* - EX bus */ +#define BCBERR_BESB_OPEX 0x00000008 /* - OpEX bus */ +#define BCBERR_BESB_OCM 0x00000010 /* - on chip memory */ +#define BCBERR_BERW 0x00000100 /* type of access */ +#define BCBERR_BERW_WRITE 0x00000000 /* - write */ +#define BCBERR_BERW_READ 0x00000100 /* - read */ +#define BCBERR_BESD 0x00000200 /* error detector */ +#define BCBERR_BESD_BCU 0x00000000 /* - BCU detected error */ +#define BCBERR_BESD_SLAVE_BUS 0x00000200 /* - slave bus detected error */ +#define BCBERR_BEBST 0x00000400 /* type of access */ +#define BCBERR_BEBST_SINGLE 0x00000000 /* - single */ +#define BCBERR_BEBST_BURST 0x00000400 /* - burst */ +#define BCBERR_BEME 0x00000800 /* multiple bus error flag */ +#define BCBERR_BEMR 0x00007000 /* master bus that caused the error */ +#define BCBERR_BEMR_NOERROR 0x00000000 /* - no error */ +#define BCBERR_BEMR_CI 0x00001000 /* - CPU instruction fetch bus caused error */ +#define BCBERR_BEMR_CD 0x00002000 /* - CPU data bus caused error */ +#define BCBERR_BEMR_DMA 0x00004000 /* - DMA bus caused error */ + +#define BCBEAR __SYSREGC(0xc0002020, u32) /* bus error address reg */ + +/* system bus controller registers */ +#define SBBASE(X) __SYSREG(0xd8c00100 + (X) * 0x10, u32) /* SBC base addr regs */ +#define SBBASE_BE 0x00000001 /* bank enable */ +#define SBBASE_BAM 0x0000fffe /* bank address mask [31:17] */ +#define SBBASE_BBA 0xfffe0000 /* bank base address [31:17] */ + +#define SBCNTRL0(X) __SYSREG(0xd8c00200 + (X) * 0x10, u32) /* SBC bank ctrl0 regs */ +#define SBCNTRL0_WEH 0x00000f00 /* write enable hold */ +#define SBCNTRL0_REH 0x0000f000 /* read enable hold */ +#define SBCNTRL0_RWH 0x000f0000 /* SRW signal hold */ +#define SBCNTRL0_CSH 0x00f00000 /* chip select hold */ +#define SBCNTRL0_DAH 0x0f000000 /* data hold */ +#define SBCNTRL0_ADH 0xf0000000 /* address hold */ + +#define SBCNTRL1(X) __SYSREG(0xd8c00204 + (X) * 0x10, u32) /* SBC bank ctrl1 regs */ +#define SBCNTRL1_WED 0x00000f00 /* write enable delay */ +#define SBCNTRL1_RED 0x0000f000 /* read enable delay */ +#define SBCNTRL1_RWD 0x000f0000 /* SRW signal delay */ +#define SBCNTRL1_ASW 0x00f00000 /* address strobe width */ +#define SBCNTRL1_CSD 0x0f000000 /* chip select delay */ +#define SBCNTRL1_ASD 0xf0000000 /* address strobe delay */ + +#define SBCNTRL2(X) __SYSREG(0xd8c00208 + (X) * 0x10, u32) /* SBC bank ctrl2 regs */ +#define SBCNTRL2_WC 0x000000ff /* wait count */ +#define SBCNTRL2_BWC 0x00000f00 /* burst wait count */ +#define SBCNTRL2_WM 0x01000000 /* wait mode setting */ +#define SBCNTRL2_WM_FIXEDWAIT 0x00000000 /* - fixed wait access */ +#define SBCNTRL2_WM_HANDSHAKE 0x01000000 /* - handshake access */ +#define SBCNTRL2_BM 0x02000000 /* bus synchronisation mode */ +#define SBCNTRL2_BM_SYNC 0x00000000 /* - synchronous mode */ +#define SBCNTRL2_BM_ASYNC 0x02000000 /* - asynchronous mode */ +#define SBCNTRL2_BW 0x04000000 /* bus width */ +#define SBCNTRL2_BW_32 0x00000000 /* - 32 bits */ +#define SBCNTRL2_BW_16 0x04000000 /* - 16 bits */ +#define SBCNTRL2_RWINV 0x08000000 /* R/W signal invert polarity */ +#define SBCNTRL2_RWINV_NORM 0x00000000 /* - normal (read high) */ +#define SBCNTRL2_RWINV_INV 0x08000000 /* - inverted (read low) */ +#define SBCNTRL2_BT 0x70000000 /* bus type setting */ +#define SBCNTRL2_BT_SRAM 0x00000000 /* - SRAM interface */ +#define SBCNTRL2_BT_ADMUX 0x00000000 /* - addr/data multiplexed interface */ +#define SBCNTRL2_BT_BROM 0x00000000 /* - burst ROM interface */ +#define SBCNTRL2_BTSE 0x80000000 /* burst enable */ + +/* memory bus controller */ +#define SDBASE(X) __SYSREG(0xda000008 + (X) * 0x4, u32) /* MBC base addr regs */ +#define SDBASE_CE 0x00000001 /* chip enable */ +#define SDBASE_CBAM 0x0000fff0 /* chip base address mask [31:20] */ +#define SDBASE_CBAM_SHIFT 16 +#define SDBASE_CBA 0xfff00000 /* chip base address [31:20] */ + +#define SDRAMBUS __SYSREG(0xda000000, u32) /* bus mode control reg */ +#define SDRAMBUS_REFEN 0x00000004 /* refresh enable */ +#define SDRAMBUS_TRC 0x00000018 /* refresh command delay time */ +#define SDRAMBUS_BSTPT 0x00000020 /* burst stop command enable */ +#define SDRAMBUS_PONSEQ 0x00000040 /* power on sequence */ +#define SDRAMBUS_SELFREQ 0x00000080 /* self-refresh mode request */ +#define SDRAMBUS_SELFON 0x00000100 /* self-refresh mode on */ +#define SDRAMBUS_SIZE 0x00030000 /* SDRAM size */ +#define SDRAMBUS_SIZE_64Mbit 0x00010000 /* 64Mbit SDRAM (x16) */ +#define SDRAMBUS_SIZE_128Mbit 0x00020000 /* 128Mbit SDRAM (x16) */ +#define SDRAMBUS_SIZE_256Mbit 0x00030000 /* 256Mbit SDRAM (x16) */ +#define SDRAMBUS_TRASWAIT 0x000c0000 /* row address precharge command cycle number */ +#define SDRAMBUS_REFNUM 0x00300000 /* refresh command number */ +#define SDRAMBUS_BSTWAIT 0x00c00000 /* burst stop command cycle */ +#define SDRAMBUS_SETWAIT 0x03000000 /* mode register setting command cycle */ +#define SDRAMBUS_PREWAIT 0x0c000000 /* precharge command cycle */ +#define SDRAMBUS_RASLATE 0x30000000 /* RAS latency */ +#define SDRAMBUS_CASLATE 0xc0000000 /* CAS latency */ + +#define SDREFCNT __SYSREG(0xda000004, u32) /* refresh period reg */ +#define SDREFCNT_PERI 0x00000fff /* refresh period */ + +#define SDSHDW __SYSREG(0xda000010, u32) /* test reg */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_BUSCTL_REGS_H */ diff --git a/arch/mn10300/include/asm/byteorder.h b/arch/mn10300/include/asm/byteorder.h new file mode 100644 index 0000000..5dd0bdd --- /dev/null +++ b/arch/mn10300/include/asm/byteorder.h @@ -0,0 +1,6 @@ +#ifndef _ASM_BYTEORDER_H +#define _ASM_BYTEORDER_H + +#include <linux/byteorder/little_endian.h> + +#endif /* _ASM_BYTEORDER_H */ diff --git a/arch/mn10300/include/asm/cache.h b/arch/mn10300/include/asm/cache.h new file mode 100644 index 0000000..e03cfa2 --- /dev/null +++ b/arch/mn10300/include/asm/cache.h @@ -0,0 +1,54 @@ +/* MN10300 cache management registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_CACHE_H +#define _ASM_CACHE_H + +#include <asm/cpu-regs.h> +#include <proc/cache.h> + +#ifndef __ASSEMBLY__ +#define L1_CACHE_DISPARITY (L1_CACHE_NENTRIES * L1_CACHE_BYTES) +#else +#define L1_CACHE_DISPARITY L1_CACHE_NENTRIES * L1_CACHE_BYTES +#endif + +/* data cache purge registers + * - read from the register to unconditionally purge that cache line + * - write address & 0xffffff00 to conditionally purge that cache line + * - clear LSB to request invalidation as well + */ +#define DCACHE_PURGE(WAY, ENTRY) \ + __SYSREG(0xc8400000 + (WAY) * L1_CACHE_WAYDISP + \ + (ENTRY) * L1_CACHE_BYTES, u32) + +#define DCACHE_PURGE_WAY0(ENTRY) \ + __SYSREG(0xc8400000 + 0 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32) +#define DCACHE_PURGE_WAY1(ENTRY) \ + __SYSREG(0xc8400000 + 1 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32) +#define DCACHE_PURGE_WAY2(ENTRY) \ + __SYSREG(0xc8400000 + 2 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32) +#define DCACHE_PURGE_WAY3(ENTRY) \ + __SYSREG(0xc8400000 + 3 * L1_CACHE_WAYDISP + (ENTRY) * L1_CACHE_BYTES, u32) + +/* instruction cache access registers */ +#define ICACHE_DATA(WAY, ENTRY, OFF) \ + __SYSREG(0xc8000000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10 + (OFF) * 4, u32) +#define ICACHE_TAG(WAY, ENTRY) \ + __SYSREG(0xc8100000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10, u32) + +/* instruction cache access registers */ +#define DCACHE_DATA(WAY, ENTRY, OFF) \ + __SYSREG(0xc8200000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10 + (OFF) * 4, u32) +#define DCACHE_TAG(WAY, ENTRY) \ + __SYSREG(0xc8300000 + (WAY) * L1_CACHE_WAYDISP + (ENTRY) * 0x10, u32) + +#endif /* _ASM_CACHE_H */ diff --git a/arch/mn10300/include/asm/cacheflush.h b/arch/mn10300/include/asm/cacheflush.h new file mode 100644 index 0000000..2db746a --- /dev/null +++ b/arch/mn10300/include/asm/cacheflush.h @@ -0,0 +1,116 @@ +/* MN10300 Cache flushing + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CACHEFLUSH_H +#define _ASM_CACHEFLUSH_H + +#ifndef __ASSEMBLY__ + +/* Keep includes the same across arches. */ +#include <linux/mm.h> + +/* + * virtually-indexed cache managment (our cache is physically indexed) + */ +#define flush_cache_all() do {} while (0) +#define flush_cache_mm(mm) do {} while (0) +#define flush_cache_dup_mm(mm) do {} while (0) +#define flush_cache_range(mm, start, end) do {} while (0) +#define flush_cache_page(vma, vmaddr, pfn) do {} while (0) +#define flush_cache_vmap(start, end) do {} while (0) +#define flush_cache_vunmap(start, end) do {} while (0) +#define flush_dcache_page(page) do {} while (0) +#define flush_dcache_mmap_lock(mapping) do {} while (0) +#define flush_dcache_mmap_unlock(mapping) do {} while (0) + +/* + * physically-indexed cache managment + */ +#ifndef CONFIG_MN10300_CACHE_DISABLED + +extern void flush_icache_range(unsigned long start, unsigned long end); +extern void flush_icache_page(struct vm_area_struct *vma, struct page *pg); + +#else + +#define flush_icache_range(start, end) do {} while (0) +#define flush_icache_page(vma, pg) do {} while (0) + +#endif + +#define flush_icache_user_range(vma, pg, adr, len) \ + flush_icache_range(adr, adr + len) + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + memcpy(dst, src, len); \ + flush_icache_page(vma, page); \ + } while (0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy(dst, src, len) + +/* + * primitive routines + */ +#ifndef CONFIG_MN10300_CACHE_DISABLED +extern void mn10300_icache_inv(void); +extern void mn10300_dcache_inv(void); +extern void mn10300_dcache_inv_page(unsigned start); +extern void mn10300_dcache_inv_range(unsigned start, unsigned end); +extern void mn10300_dcache_inv_range2(unsigned start, unsigned size); +#ifdef CONFIG_MN10300_CACHE_WBACK +extern void mn10300_dcache_flush(void); +extern void mn10300_dcache_flush_page(unsigned start); +extern void mn10300_dcache_flush_range(unsigned start, unsigned end); +extern void mn10300_dcache_flush_range2(unsigned start, unsigned size); +extern void mn10300_dcache_flush_inv(void); +extern void mn10300_dcache_flush_inv_page(unsigned start); +extern void mn10300_dcache_flush_inv_range(unsigned start, unsigned end); +extern void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size); +#else +#define mn10300_dcache_flush() do {} while (0) +#define mn10300_dcache_flush_page(start) do {} while (0) +#define mn10300_dcache_flush_range(start, end) do {} while (0) +#define mn10300_dcache_flush_range2(start, size) do {} while (0) +#define mn10300_dcache_flush_inv() mn10300_dcache_inv() +#define mn10300_dcache_flush_inv_page(start) \ + mn10300_dcache_inv_page((start)) +#define mn10300_dcache_flush_inv_range(start, end) \ + mn10300_dcache_inv_range((start), (end)) +#define mn10300_dcache_flush_inv_range2(start, size) \ + mn10300_dcache_inv_range2((start), (size)) +#endif /* CONFIG_MN10300_CACHE_WBACK */ +#else +#define mn10300_icache_inv() do {} while (0) +#define mn10300_dcache_inv() do {} while (0) +#define mn10300_dcache_inv_page(start) do {} while (0) +#define mn10300_dcache_inv_range(start, end) do {} while (0) +#define mn10300_dcache_inv_range2(start, size) do {} while (0) +#define mn10300_dcache_flush() do {} while (0) +#define mn10300_dcache_flush_inv_page(start) do {} while (0) +#define mn10300_dcache_flush_inv() do {} while (0) +#define mn10300_dcache_flush_inv_range(start, end) do {} while (0) +#define mn10300_dcache_flush_inv_range2(start, size) do {} while (0) +#define mn10300_dcache_flush_page(start) do {} while (0) +#define mn10300_dcache_flush_range(start, end) do {} while (0) +#define mn10300_dcache_flush_range2(start, size) do {} while (0) +#endif /* CONFIG_MN10300_CACHE_DISABLED */ + +/* + * internal debugging function + */ +#ifdef CONFIG_DEBUG_PAGEALLOC +extern void kernel_map_pages(struct page *page, int numpages, int enable); +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_CACHEFLUSH_H */ diff --git a/arch/mn10300/include/asm/checksum.h b/arch/mn10300/include/asm/checksum.h new file mode 100644 index 0000000..9fb2a8d --- /dev/null +++ b/arch/mn10300/include/asm/checksum.h @@ -0,0 +1,86 @@ +/* MN10300 Optimised checksumming code + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CHECKSUM_H +#define _ASM_CHECKSUM_H + +extern __wsum csum_partial(const void *buff, int len, __wsum sum); +extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum); +extern __wsum csum_partial_copy_from_user(const void *src, void *dst, + int len, __wsum sum, + int *err_ptr); +extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); +extern __wsum csum_partial(const void *buff, int len, __wsum sum); +extern __sum16 ip_compute_csum(const void *buff, int len); + +#define csum_partial_copy_fromuser csum_partial_copy +extern __wsum csum_partial_copy(const void *src, void *dst, int len, + __wsum sum); + +static inline __sum16 csum_fold(__wsum sum) +{ + asm( + " add %1,%0 \n" + " addc 0xffff,%0 \n" + : "=r" (sum) + : "r" (sum << 16), "0" (sum & 0xffff0000) + : "cc" + ); + return (~sum) >> 16; +} + +static inline __wsum csum_tcpudp_nofold(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + __wsum tmp; + + tmp = (__wsum) ntohs(len) << 16; + tmp += (__wsum) proto << 8; + + asm( + " add %1,%0 \n" + " addc %2,%0 \n" + " addc %3,%0 \n" + " addc 0,%0 \n" + : "=r" (sum) + : "r" (daddr), "r"(saddr), "r"(tmp), "0"(sum) + : "cc" + ); + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + +#undef _HAVE_ARCH_IPV6_CSUM + +/* + * Copy and checksum to user + */ +#define HAVE_CSUM_COPY_USER +extern __wsum csum_and_copy_to_user(const void *src, void *dst, int len, + __wsum sum, int *err_ptr); + + +#endif /* _ASM_CHECKSUM_H */ diff --git a/arch/mn10300/include/asm/cpu-regs.h b/arch/mn10300/include/asm/cpu-regs.h new file mode 100644 index 0000000..757e9b5 --- /dev/null +++ b/arch/mn10300/include/asm/cpu-regs.h @@ -0,0 +1,290 @@ +/* MN10300 Core system registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CPU_REGS_H +#define _ASM_CPU_REGS_H + +#ifndef __ASSEMBLY__ +#include <linux/types.h> +#endif + +#ifdef CONFIG_MN10300_CPU_AM33V2 +/* we tell the compiler to pretend to be AM33 so that it doesn't try and use + * the FP regs, but tell the assembler that we're actually allowed AM33v2 + * instructions */ +#ifndef __ASSEMBLY__ +asm(" .am33_2\n"); +#else +.am33_2 +#endif +#endif + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +#define __SYSREG(ADDR, TYPE) (*(volatile TYPE *)(ADDR)) +#define __SYSREGC(ADDR, TYPE) (*(const volatile TYPE *)(ADDR)) +#else +#define __SYSREG(ADDR, TYPE) ADDR +#define __SYSREGC(ADDR, TYPE) ADDR +#endif + +/* CPU registers */ +#define EPSW_FLAG_Z 0x00000001 /* zero flag */ +#define EPSW_FLAG_N 0x00000002 /* negative flag */ +#define EPSW_FLAG_C 0x00000004 /* carry flag */ +#define EPSW_FLAG_V 0x00000008 /* overflow flag */ +#define EPSW_IM 0x00000700 /* interrupt mode */ +#define EPSW_IM_0 0x00000000 /* interrupt mode 0 */ +#define EPSW_IM_1 0x00000100 /* interrupt mode 1 */ +#define EPSW_IM_2 0x00000200 /* interrupt mode 2 */ +#define EPSW_IM_3 0x00000300 /* interrupt mode 3 */ +#define EPSW_IM_4 0x00000400 /* interrupt mode 4 */ +#define EPSW_IM_5 0x00000500 /* interrupt mode 5 */ +#define EPSW_IM_6 0x00000600 /* interrupt mode 6 */ +#define EPSW_IM_7 0x00000700 /* interrupt mode 7 */ +#define EPSW_IE 0x00000800 /* interrupt enable */ +#define EPSW_S 0x00003000 /* software auxilliary bits */ +#define EPSW_T 0x00008000 /* trace enable */ +#define EPSW_nSL 0x00010000 /* not supervisor level */ +#define EPSW_NMID 0x00020000 /* nonmaskable interrupt disable */ +#define EPSW_nAR 0x00040000 /* register bank control */ +#define EPSW_ML 0x00080000 /* monitor level */ +#define EPSW_FE 0x00100000 /* FPU enable */ + +/* FPU registers */ +#define FPCR_EF_I 0x00000001 /* inexact result FPU exception flag */ +#define FPCR_EF_U 0x00000002 /* underflow FPU exception flag */ +#define FPCR_EF_O 0x00000004 /* overflow FPU exception flag */ +#define FPCR_EF_Z 0x00000008 /* zero divide FPU exception flag */ +#define FPCR_EF_V 0x00000010 /* invalid operand FPU exception flag */ +#define FPCR_EE_I 0x00000020 /* inexact result FPU exception enable */ +#define FPCR_EE_U 0x00000040 /* underflow FPU exception enable */ +#define FPCR_EE_O 0x00000080 /* overflow FPU exception enable */ +#define FPCR_EE_Z 0x00000100 /* zero divide FPU exception enable */ +#define FPCR_EE_V 0x00000200 /* invalid operand FPU exception enable */ +#define FPCR_EC_I 0x00000400 /* inexact result FPU exception cause */ +#define FPCR_EC_U 0x00000800 /* underflow FPU exception cause */ +#define FPCR_EC_O 0x00001000 /* overflow FPU exception cause */ +#define FPCR_EC_Z 0x00002000 /* zero divide FPU exception cause */ +#define FPCR_EC_V 0x00004000 /* invalid operand FPU exception cause */ +#define FPCR_RM 0x00030000 /* rounding mode */ +#define FPCR_RM_NEAREST 0x00000000 /* - round to nearest value */ +#define FPCR_FCC_U 0x00040000 /* FPU unordered condition code */ +#define FPCR_FCC_E 0x00080000 /* FPU equal condition code */ +#define FPCR_FCC_G 0x00100000 /* FPU greater than condition code */ +#define FPCR_FCC_L 0x00200000 /* FPU less than condition code */ +#define FPCR_INIT 0x00000000 /* no exceptions, rounding to nearest */ + +/* CPU control registers */ +#define CPUP __SYSREG(0xc0000020, u16) /* CPU pipeline register */ +#define CPUP_DWBD 0x0020 /* write buffer disable flag */ +#define CPUP_IPFD 0x0040 /* instruction prefetch disable flag */ +#define CPUP_EXM 0x0080 /* exception operation mode */ +#define CPUP_EXM_AM33V1 0x0000 /* - AM33 v1 exception mode */ +#define CPUP_EXM_AM33V2 0x0080 /* - AM33 v2 exception mode */ + +#define CPUM __SYSREG(0xc0000040, u16) /* CPU mode register */ +#define CPUM_SLEEP 0x0004 /* set to enter sleep state */ +#define CPUM_HALT 0x0008 /* set to enter halt state */ +#define CPUM_STOP 0x0010 /* set to enter stop state */ + +#define CPUREV __SYSREGC(0xc0000050, u32) /* CPU revision register */ +#define CPUREV_TYPE 0x0000000f /* CPU type */ +#define CPUREV_TYPE_S 0 +#define CPUREV_TYPE_AM33V1 0x00000000 /* - AM33 V1 core, AM33/1.00 arch */ +#define CPUREV_TYPE_AM33V2 0x00000001 /* - AM33 V2 core, AM33/2.00 arch */ +#define CPUREV_TYPE_AM34V1 0x00000002 /* - AM34 V1 core, AM33/2.00 arch */ +#define CPUREV_REVISION 0x000000f0 /* CPU revision */ +#define CPUREV_REVISION_S 4 +#define CPUREV_ICWAY 0x00000f00 /* number of instruction cache ways */ +#define CPUREV_ICWAY_S 8 +#define CPUREV_ICSIZE 0x0000f000 /* instruction cache way size */ +#define CPUREV_ICSIZE_S 12 +#define CPUREV_DCWAY 0x000f0000 /* number of data cache ways */ +#define CPUREV_DCWAY_S 16 +#define CPUREV_DCSIZE 0x00f00000 /* data cache way size */ +#define CPUREV_DCSIZE_S 20 +#define CPUREV_FPUTYPE 0x0f000000 /* FPU core type */ +#define CPUREV_FPUTYPE_NONE 0x00000000 /* - no FPU core implemented */ +#define CPUREV_OCDCTG 0xf0000000 /* on-chip debug function category */ + +#define DCR __SYSREG(0xc0000030, u16) /* Debug control register */ + +/* interrupt/exception control registers */ +#define IVAR0 __SYSREG(0xc0000000, u16) /* interrupt vector 0 */ +#define IVAR1 __SYSREG(0xc0000004, u16) /* interrupt vector 1 */ +#define IVAR2 __SYSREG(0xc0000008, u16) /* interrupt vector 2 */ +#define IVAR3 __SYSREG(0xc000000c, u16) /* interrupt vector 3 */ +#define IVAR4 __SYSREG(0xc0000010, u16) /* interrupt vector 4 */ +#define IVAR5 __SYSREG(0xc0000014, u16) /* interrupt vector 5 */ +#define IVAR6 __SYSREG(0xc0000018, u16) /* interrupt vector 6 */ + +#define TBR __SYSREG(0xc0000024, u32) /* Trap table base */ +#define TBR_TB 0xff000000 /* table base address bits 31-24 */ +#define TBR_INT_CODE 0x00ffffff /* interrupt code */ + +#define DEAR __SYSREG(0xc0000038, u32) /* Data access exception address */ + +#define sISR __SYSREG(0xc0000044, u32) /* Supervisor interrupt status */ +#define sISR_IRQICE 0x00000001 /* ICE interrupt */ +#define sISR_ISTEP 0x00000002 /* single step interrupt */ +#define sISR_MISSA 0x00000004 /* memory access address misalignment fault */ +#define sISR_UNIMP 0x00000008 /* unimplemented instruction execution fault */ +#define sISR_PIEXE 0x00000010 /* program interrupt */ +#define sISR_MEMERR 0x00000020 /* illegal memory access fault */ +#define sISR_IBREAK 0x00000040 /* instraction break interrupt */ +#define sISR_DBSRL 0x00000080 /* debug serial interrupt */ +#define sISR_PERIDB 0x00000100 /* peripheral debug interrupt */ +#define sISR_EXUNIMP 0x00000200 /* unimplemented ex-instruction execution fault */ +#define sISR_OBREAK 0x00000400 /* operand break interrupt */ +#define sISR_PRIV 0x00000800 /* privileged instruction execution fault */ +#define sISR_BUSERR 0x00001000 /* bus error fault */ +#define sISR_DBLFT 0x00002000 /* double fault */ +#define sISR_DBG 0x00008000 /* debug reserved interrupt */ +#define sISR_ITMISS 0x00010000 /* instruction TLB miss */ +#define sISR_DTMISS 0x00020000 /* data TLB miss */ +#define sISR_ITEX 0x00040000 /* instruction TLB access exception */ +#define sISR_DTEX 0x00080000 /* data TLB access exception */ +#define sISR_ILGIA 0x00100000 /* illegal instruction access exception */ +#define sISR_ILGDA 0x00200000 /* illegal data access exception */ +#define sISR_IOIA 0x00400000 /* internal I/O space instruction access excep */ +#define sISR_PRIVA 0x00800000 /* privileged space instruction access excep */ +#define sISR_PRIDA 0x01000000 /* privileged space data access excep */ +#define sISR_DISA 0x02000000 /* data space instruction access excep */ +#define sISR_SYSC 0x04000000 /* system call instruction excep */ +#define sISR_FPUD 0x08000000 /* FPU disabled excep */ +#define sISR_FPUUI 0x10000000 /* FPU unimplemented instruction excep */ +#define sISR_FPUOP 0x20000000 /* FPU operation excep */ +#define sISR_NE 0x80000000 /* multiple synchronous exceptions excep */ + +/* cache control registers */ +#define CHCTR __SYSREG(0xc0000070, u16) /* cache control */ +#define CHCTR_ICEN 0x0001 /* instruction cache enable */ +#define CHCTR_DCEN 0x0002 /* data cache enable */ +#define CHCTR_ICBUSY 0x0004 /* instruction cache busy */ +#define CHCTR_DCBUSY 0x0008 /* data cache busy */ +#define CHCTR_ICINV 0x0010 /* instruction cache invalidate */ +#define CHCTR_DCINV 0x0020 /* data cache invalidate */ +#define CHCTR_DCWTMD 0x0040 /* data cache writing mode */ +#define CHCTR_DCWTMD_WRBACK 0x0000 /* - write back mode */ +#define CHCTR_DCWTMD_WRTHROUGH 0x0040 /* - write through mode */ +#define CHCTR_DCALMD 0x0080 /* data cache allocation mode */ +#define CHCTR_ICWMD 0x0f00 /* instruction cache way mode */ +#define CHCTR_DCWMD 0xf000 /* data cache way mode */ + +/* MMU control registers */ +#define MMUCTR __SYSREG(0xc0000090, u32) /* MMU control register */ +#define MMUCTR_IRP 0x0000003f /* instruction TLB replace pointer */ +#define MMUCTR_ITE 0x00000040 /* instruction TLB enable */ +#define MMUCTR_IIV 0x00000080 /* instruction TLB invalidate */ +#define MMUCTR_ITL 0x00000700 /* instruction TLB lock pointer */ +#define MMUCTR_ITL_NOLOCK 0x00000000 /* - no lock */ +#define MMUCTR_ITL_LOCK0 0x00000100 /* - entry 0 locked */ +#define MMUCTR_ITL_LOCK0_1 0x00000200 /* - entry 0-1 locked */ +#define MMUCTR_ITL_LOCK0_3 0x00000300 /* - entry 0-3 locked */ +#define MMUCTR_ITL_LOCK0_7 0x00000400 /* - entry 0-7 locked */ +#define MMUCTR_ITL_LOCK0_15 0x00000500 /* - entry 0-15 locked */ +#define MMUCTR_CE 0x00008000 /* cacheable bit enable */ +#define MMUCTR_DRP 0x003f0000 /* data TLB replace pointer */ +#define MMUCTR_DTE 0x00400000 /* data TLB enable */ +#define MMUCTR_DIV 0x00800000 /* data TLB invalidate */ +#define MMUCTR_DTL 0x07000000 /* data TLB lock pointer */ +#define MMUCTR_DTL_NOLOCK 0x00000000 /* - no lock */ +#define MMUCTR_DTL_LOCK0 0x01000000 /* - entry 0 locked */ +#define MMUCTR_DTL_LOCK0_1 0x02000000 /* - entry 0-1 locked */ +#define MMUCTR_DTL_LOCK0_3 0x03000000 /* - entry 0-3 locked */ +#define MMUCTR_DTL_LOCK0_7 0x04000000 /* - entry 0-7 locked */ +#define MMUCTR_DTL_LOCK0_15 0x05000000 /* - entry 0-15 locked */ + +#define PIDR __SYSREG(0xc0000094, u16) /* PID register */ +#define PIDR_PID 0x00ff /* process identifier */ + +#define PTBR __SYSREG(0xc0000098, unsigned long) /* Page table base register */ + +#define IPTEL __SYSREG(0xc00000a0, u32) /* instruction TLB entry */ +#define DPTEL __SYSREG(0xc00000b0, u32) /* data TLB entry */ +#define xPTEL_V 0x00000001 /* TLB entry valid */ +#define xPTEL_UNUSED1 0x00000002 /* unused bit */ +#define xPTEL_UNUSED2 0x00000004 /* unused bit */ +#define xPTEL_C 0x00000008 /* cached if set */ +#define xPTEL_PV 0x00000010 /* page valid */ +#define xPTEL_D 0x00000020 /* dirty */ +#define xPTEL_PR 0x000001c0 /* page protection */ +#define xPTEL_PR_ROK 0x00000000 /* - R/O kernel */ +#define xPTEL_PR_RWK 0x00000100 /* - R/W kernel */ +#define xPTEL_PR_ROK_ROU 0x00000080 /* - R/O kernel and R/O user */ +#define xPTEL_PR_RWK_ROU 0x00000180 /* - R/W kernel and R/O user */ +#define xPTEL_PR_RWK_RWU 0x000001c0 /* - R/W kernel and R/W user */ +#define xPTEL_G 0x00000200 /* global (use PID if 0) */ +#define xPTEL_PS 0x00000c00 /* page size */ +#define xPTEL_PS_4Kb 0x00000000 /* - 4Kb page */ +#define xPTEL_PS_128Kb 0x00000400 /* - 128Kb page */ +#define xPTEL_PS_1Kb 0x00000800 /* - 1Kb page */ +#define xPTEL_PS_4Mb 0x00000c00 /* - 4Mb page */ +#define xPTEL_PPN 0xfffff006 /* physical page number */ + +#define xPTEL_V_BIT 0 /* bit numbers corresponding to above masks */ +#define xPTEL_UNUSED1_BIT 1 +#define xPTEL_UNUSED2_BIT 2 +#define xPTEL_C_BIT 3 +#define xPTEL_PV_BIT 4 +#define xPTEL_D_BIT 5 +#define xPTEL_G_BIT 9 + +#define IPTEU __SYSREG(0xc00000a4, u32) /* instruction TLB virtual addr */ +#define DPTEU __SYSREG(0xc00000b4, u32) /* data TLB virtual addr */ +#define xPTEU_VPN 0xfffffc00 /* virtual page number */ +#define xPTEU_PID 0x000000ff /* process identifier to which applicable */ + +#define IPTEL2 __SYSREG(0xc00000a8, u32) /* instruction TLB entry */ +#define DPTEL2 __SYSREG(0xc00000b8, u32) /* data TLB entry */ +#define xPTEL2_V 0x00000001 /* TLB entry valid */ +#define xPTEL2_C 0x00000002 /* cacheable */ +#define xPTEL2_PV 0x00000004 /* page valid */ +#define xPTEL2_D 0x00000008 /* dirty */ +#define xPTEL2_PR 0x00000070 /* page protection */ +#define xPTEL2_PR_ROK 0x00000000 /* - R/O kernel */ +#define xPTEL2_PR_RWK 0x00000040 /* - R/W kernel */ +#define xPTEL2_PR_ROK_ROU 0x00000020 /* - R/O kernel and R/O user */ +#define xPTEL2_PR_RWK_ROU 0x00000060 /* - R/W kernel and R/O user */ +#define xPTEL2_PR_RWK_RWU 0x00000070 /* - R/W kernel and R/W user */ +#define xPTEL2_G 0x00000080 /* global (use PID if 0) */ +#define xPTEL2_PS 0x00000300 /* page size */ +#define xPTEL2_PS_4Kb 0x00000000 /* - 4Kb page */ +#define xPTEL2_PS_128Kb 0x00000100 /* - 128Kb page */ +#define xPTEL2_PS_1Kb 0x00000200 /* - 1Kb page */ +#define xPTEL2_PS_4Mb 0x00000300 /* - 4Mb page */ +#define xPTEL2_PPN 0xfffffc00 /* physical page number */ + +#define MMUFCR __SYSREGC(0xc000009c, u32) /* MMU exception cause */ +#define MMUFCR_IFC __SYSREGC(0xc000009c, u16) /* MMU instruction excep cause */ +#define MMUFCR_DFC __SYSREGC(0xc000009e, u16) /* MMU data exception cause */ +#define MMUFCR_xFC_TLBMISS 0x0001 /* TLB miss flag */ +#define MMUFCR_xFC_INITWR 0x0002 /* initial write excep flag */ +#define MMUFCR_xFC_PGINVAL 0x0004 /* page invalid excep flag */ +#define MMUFCR_xFC_PROTVIOL 0x0008 /* protection violation excep flag */ +#define MMUFCR_xFC_ACCESS 0x0010 /* access level flag */ +#define MMUFCR_xFC_ACCESS_USR 0x0000 /* - user mode */ +#define MMUFCR_xFC_ACCESS_SR 0x0010 /* - supervisor mode */ +#define MMUFCR_xFC_TYPE 0x0020 /* access type flag */ +#define MMUFCR_xFC_TYPE_READ 0x0000 /* - read */ +#define MMUFCR_xFC_TYPE_WRITE 0x0020 /* - write */ +#define MMUFCR_xFC_PR 0x01c0 /* page protection flag */ +#define MMUFCR_xFC_PR_ROK 0x0000 /* - R/O kernel */ +#define MMUFCR_xFC_PR_RWK 0x0100 /* - R/W kernel */ +#define MMUFCR_xFC_PR_ROK_ROU 0x0080 /* - R/O kernel and R/O user */ +#define MMUFCR_xFC_PR_RWK_ROU 0x0180 /* - R/W kernel and R/O user */ +#define MMUFCR_xFC_PR_RWK_RWU 0x01c0 /* - R/W kernel and R/W user */ +#define MMUFCR_xFC_ILLADDR 0x0200 /* illegal address excep flag */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_CPU_REGS_H */ diff --git a/arch/mn10300/include/asm/cputime.h b/arch/mn10300/include/asm/cputime.h new file mode 100644 index 0000000..6d68ad7 --- /dev/null +++ b/arch/mn10300/include/asm/cputime.h @@ -0,0 +1 @@ +#include <asm-generic/cputime.h> diff --git a/arch/mn10300/include/asm/current.h b/arch/mn10300/include/asm/current.h new file mode 100644 index 0000000..ca6027d --- /dev/null +++ b/arch/mn10300/include/asm/current.h @@ -0,0 +1,37 @@ +/* MN10300 Current task structure accessor + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_CURRENT_H +#define _ASM_CURRENT_H + +#include <linux/thread_info.h> + +/* + * dedicate E2 to keeping the current task pointer + */ +#ifdef CONFIG_MN10300_CURRENT_IN_E2 + +register struct task_struct *const current asm("e2") __attribute__((used)); + +#define get_current() current + +extern struct task_struct *__current; + +#else +static inline __attribute__((const)) +struct task_struct *get_current(void) +{ + return current_thread_info()->task; +} + +#define current get_current() +#endif + +#endif /* _ASM_CURRENT_H */ diff --git a/arch/mn10300/include/asm/delay.h b/arch/mn10300/include/asm/delay.h new file mode 100644 index 0000000..34517b3 --- /dev/null +++ b/arch/mn10300/include/asm/delay.h @@ -0,0 +1,19 @@ +/* MN10300 Uninterruptible delay routines + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DELAY_H +#define _ASM_DELAY_H + +extern void __udelay(unsigned long usecs); +extern void __delay(unsigned long loops); + +#define udelay(n) __udelay(n) + +#endif /* _ASM_DELAY_H */ diff --git a/arch/mn10300/include/asm/device.h b/arch/mn10300/include/asm/device.h new file mode 100644 index 0000000..f0a4c25 --- /dev/null +++ b/arch/mn10300/include/asm/device.h @@ -0,0 +1 @@ +#include <asm-generic/device.h> diff --git a/arch/mn10300/include/asm/div64.h b/arch/mn10300/include/asm/div64.h new file mode 100644 index 0000000..3a8329b --- /dev/null +++ b/arch/mn10300/include/asm/div64.h @@ -0,0 +1,100 @@ +/* MN10300 64-bit division + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DIV64 +#define _ASM_DIV64 + +#include <linux/types.h> + +extern void ____unhandled_size_in_do_div___(void); + +/* + * divide n by base, leaving the result in n and returning the remainder + * - we can do this quite efficiently on the MN10300 by cascading the divides + * through the MDR register + */ +#define do_div(n, base) \ +({ \ + unsigned __rem = 0; \ + if (sizeof(n) <= 4) { \ + asm("mov %1,mdr \n" \ + "divu %2,%0 \n" \ + "mov mdr,%1 \n" \ + : "+r"(n), "=d"(__rem) \ + : "r"(base), "1"(__rem) \ + : "cc" \ + ); \ + } else if (sizeof(n) <= 8) { \ + union { \ + unsigned long long l; \ + u32 w[2]; \ + } __quot; \ + __quot.l = n; \ + asm("mov %0,mdr \n" /* MDR = 0 */ \ + "divu %3,%1 \n" \ + /* __quot.MSL = __div.MSL / base, */ \ + /* MDR = MDR:__div.MSL % base */ \ + "divu %3,%2 \n" \ + /* __quot.LSL = MDR:__div.LSL / base, */ \ + /* MDR = MDR:__div.LSL % base */ \ + "mov mdr,%0 \n" \ + : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0]) \ + : "r"(base), "0"(__rem), "1"(__quot.w[1]), \ + "2"(__quot.w[0]) \ + : "cc" \ + ); \ + n = __quot.l; \ + } else { \ + ____unhandled_size_in_do_div___(); \ + } \ + __rem; \ +}) + +/* + * do an unsigned 32-bit multiply and divide with intermediate 64-bit product + * so as not to lose accuracy + * - we use the MDR register to hold the MSW of the product + */ +static inline __attribute__((const)) +unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div) +{ + unsigned result; + + asm("mulu %2,%0 \n" /* MDR:val = val*mult */ + "divu %3,%0 \n" /* val = MDR:val/div; + * MDR = MDR:val%div */ + : "=r"(result) + : "0"(val), "ir"(mult), "r"(div) + ); + + return result; +} + +/* + * do a signed 32-bit multiply and divide with intermediate 64-bit product so + * as not to lose accuracy + * - we use the MDR register to hold the MSW of the product + */ +static inline __attribute__((const)) +signed __muldiv64s(signed val, signed mult, signed div) +{ + signed result; + + asm("mul %2,%0 \n" /* MDR:val = val*mult */ + "div %3,%0 \n" /* val = MDR:val/div; + * MDR = MDR:val%div */ + : "=r"(result) + : "0"(val), "ir"(mult), "r"(div) + ); + + return result; +} + +#endif /* _ASM_DIV64 */ diff --git a/arch/mn10300/include/asm/dma-mapping.h b/arch/mn10300/include/asm/dma-mapping.h new file mode 100644 index 0000000..ccae8f6 --- /dev/null +++ b/arch/mn10300/include/asm/dma-mapping.h @@ -0,0 +1,234 @@ +/* DMA mapping routines for the MN10300 arch + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DMA_MAPPING_H +#define _ASM_DMA_MAPPING_H + +#include <linux/mm.h> +#include <linux/scatterlist.h> + +#include <asm/cache.h> +#include <asm/io.h> + +extern void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, int flag); + +extern void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f)) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h)) + +/* + * Map a single buffer of the indicated size for DMA in streaming mode. The + * 32-bit bus address to use is returned. + * + * Once the device is given the dma address, the device owns this memory until + * either pci_unmap_single or pci_dma_sync_single is performed. + */ +static inline +dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + mn10300_dcache_flush_inv(); + return virt_to_bus(ptr); +} + +/* + * Unmap a single streaming mode DMA translation. The dma_addr and size must + * match what was provided for in a previous pci_map_single call. All other + * usages are undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see + * whatever the device wrote there. + */ +static inline +void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +/* + * Map a set of buffers described by scatterlist in streaming mode for DMA. + * This is the scather-gather version of the above pci_map_single interface. + * Here the scatter gather list elements are each tagged with the appropriate + * dma address and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of DMA + * address/length pairs than there are SG table elements. (for example + * via virtual mapping capabilities) The routine returns the number of + * addr/length pairs actually used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are the same + * here. + */ +static inline +int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, + enum dma_data_direction direction) +{ + struct scatterlist *sg; + int i; + + BUG_ON(!valid_dma_direction(direction)); + WARN_ON(nents == 0 || sglist[0].length == 0); + + for_each_sg(sglist, sg, nents, i) { + BUG_ON(!sg_page(sg)); + + sg->dma_address = sg_phys(sg); + } + + mn10300_dcache_flush_inv(); + return nents; +} + +/* + * Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +static inline +void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) +{ + BUG_ON(!valid_dma_direction(direction)); +} + +/* + * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical + * to pci_map_single, but takes a struct page instead of a virtual address + */ +static inline +dma_addr_t dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + return page_to_bus(page) + offset; +} + +static inline +void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); +} + +/* + * Make physical memory consistent for a single streaming mode DMA translation + * after a transfer. + * + * If you perform a pci_map_single() but wish to interrogate the buffer using + * the cpu, yet do not wish to teardown the PCI dma mapping, you must call this + * function before doing so. At the next point you give the PCI dma address + * back to the card, the device again owns the buffer. + */ +static inline +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ +} + +static inline +void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + mn10300_dcache_flush_inv(); +} + +static inline +void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ +} + +static inline void +dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + mn10300_dcache_flush_inv(); +} + + +/* + * Make physical memory consistent for a set of streaming mode DMA translations + * after a transfer. + * + * The same as pci_dma_sync_single but for a scatter-gather list, same rules + * and usage. + */ +static inline +void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, + int nelems, enum dma_data_direction direction) +{ +} + +static inline +void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, + int nelems, enum dma_data_direction direction) +{ + mn10300_dcache_flush_inv(); +} + +static inline +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} + +/* + * Return whether the given PCI device DMA address mask can be supported + * properly. For example, if your device can only drive the low 24-bits during + * PCI bus mastering, then you would pass 0x00ffffff as the mask to this + * function. + */ +static inline +int dma_supported(struct device *dev, u64 mask) +{ + /* + * we fall back to GFP_DMA when the mask isn't all 1s, so we can't + * guarantee allocations that must be within a tighter range than + * GFP_DMA + */ + if (mask < 0x00ffffff) + return 0; + return 1; +} + +static inline +int dma_set_mask(struct device *dev, u64 mask) +{ + if (!dev->dma_mask || !dma_supported(dev, mask)) + return -EIO; + + *dev->dma_mask = mask; + return 0; +} + +static inline +int dma_get_cache_alignment(void) +{ + return 1 << L1_CACHE_SHIFT; +} + +#define dma_is_consistent(d) (1) + +static inline +void dma_cache_sync(void *vaddr, size_t size, + enum dma_data_direction direction) +{ + mn10300_dcache_flush_inv(); +} + +#endif diff --git a/arch/mn10300/include/asm/dma.h b/arch/mn10300/include/asm/dma.h new file mode 100644 index 0000000..098df2e --- /dev/null +++ b/arch/mn10300/include/asm/dma.h @@ -0,0 +1,118 @@ +/* MN10300 ISA DMA handlers and definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DMA_H +#define _ASM_DMA_H + +#include <asm/system.h> +#include <linux/spinlock.h> +#include <asm/io.h> +#include <linux/delay.h> + +#undef MAX_DMA_CHANNELS /* switch off linux/kernel/dma.c */ +#define MAX_DMA_ADDRESS 0xbfffffff + +extern spinlock_t dma_spin_lock; + +static inline unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static inline void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* enable/disable a specific DMA channel */ +static inline void enable_dma(unsigned int dmanr) +{ +} + +static inline void disable_dma(unsigned int dmanr) +{ +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while holding the DMA lock ! --- + */ +static inline void clear_dma_ff(unsigned int dmanr) +{ +} + +/* set mode (above) for a specific DMA channel */ +static inline void set_dma_mode(unsigned int dmanr, char mode) +{ +} + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static inline void set_dma_page(unsigned int dmanr, char pagenr) +{ +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static inline void set_dma_addr(unsigned int dmanr, unsigned int a) +{ +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static inline void set_dma_count(unsigned int dmanr, unsigned int count) +{ +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static inline int get_dma_residue(unsigned int dmanr) +{ + return 0; +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char *device_id); +extern void free_dma(unsigned int dmanr); + +/* From PCI */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif + +#endif /* _ASM_DMA_H */ diff --git a/arch/mn10300/include/asm/dmactl-regs.h b/arch/mn10300/include/asm/dmactl-regs.h new file mode 100644 index 0000000..58a199d --- /dev/null +++ b/arch/mn10300/include/asm/dmactl-regs.h @@ -0,0 +1,101 @@ +/* MN10300 on-board DMA controller registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_DMACTL_REGS_H +#define _ASM_DMACTL_REGS_H + +#include <asm/cpu-regs.h> + +#ifdef __KERNEL__ + +/* DMA registers */ +#define DMxCTR(N) __SYSREG(0xd2000000 + ((N) * 0x100), u32) /* control reg */ +#define DMxCTR_BG 0x0000001f /* transfer request source */ +#define DMxCTR_BG_SOFT 0x00000000 /* - software source */ +#define DMxCTR_BG_SC0TX 0x00000002 /* - serial port 0 transmission */ +#define DMxCTR_BG_SC0RX 0x00000003 /* - serial port 0 reception */ +#define DMxCTR_BG_SC1TX 0x00000004 /* - serial port 1 transmission */ +#define DMxCTR_BG_SC1RX 0x00000005 /* - serial port 1 reception */ +#define DMxCTR_BG_SC2TX 0x00000006 /* - serial port 2 transmission */ +#define DMxCTR_BG_SC2RX 0x00000007 /* - serial port 2 reception */ +#define DMxCTR_BG_TM0UFLOW 0x00000008 /* - timer 0 underflow */ +#define DMxCTR_BG_TM1UFLOW 0x00000009 /* - timer 1 underflow */ +#define DMxCTR_BG_TM2UFLOW 0x0000000a /* - timer 2 underflow */ +#define DMxCTR_BG_TM3UFLOW 0x0000000b /* - timer 3 underflow */ +#define DMxCTR_BG_TM6ACMPCAP 0x0000000c /* - timer 6A compare/capture */ +#define DMxCTR_BG_AFE 0x0000000d /* - analogue front-end interrupt source */ +#define DMxCTR_BG_ADC 0x0000000e /* - A/D conversion end interrupt source */ +#define DMxCTR_BG_IRDA 0x0000000f /* - IrDA interrupt source */ +#define DMxCTR_BG_RTC 0x00000010 /* - RTC interrupt source */ +#define DMxCTR_BG_XIRQ0 0x00000011 /* - XIRQ0 pin interrupt source */ +#define DMxCTR_BG_XIRQ1 0x00000012 /* - XIRQ1 pin interrupt source */ +#define DMxCTR_BG_XDMR0 0x00000013 /* - external request 0 source (XDMR0 pin) */ +#define DMxCTR_BG_XDMR1 0x00000014 /* - external request 1 source (XDMR1 pin) */ +#define DMxCTR_SAM 0x000000e0 /* DMA transfer src addr mode */ +#define DMxCTR_SAM_INCR 0x00000000 /* - increment */ +#define DMxCTR_SAM_DECR 0x00000020 /* - decrement */ +#define DMxCTR_SAM_FIXED 0x00000040 /* - fixed */ +#define DMxCTR_DAM 0x00000000 /* DMA transfer dest addr mode */ +#define DMxCTR_DAM_INCR 0x00000000 /* - increment */ +#define DMxCTR_DAM_DECR 0x00000100 /* - decrement */ +#define DMxCTR_DAM_FIXED 0x00000200 /* - fixed */ +#define DMxCTR_TM 0x00001800 /* DMA transfer mode */ +#define DMxCTR_TM_BATCH 0x00000000 /* - batch transfer */ +#define DMxCTR_TM_INTERM 0x00001000 /* - intermittent transfer */ +#define DMxCTR_UT 0x00006000 /* DMA transfer unit */ +#define DMxCTR_UT_1 0x00000000 /* - 1 byte */ +#define DMxCTR_UT_2 0x00002000 /* - 2 byte */ +#define DMxCTR_UT_4 0x00004000 /* - 4 byte */ +#define DMxCTR_UT_16 0x00006000 /* - 16 byte */ +#define DMxCTR_TEN 0x00010000 /* DMA channel transfer enable */ +#define DMxCTR_RQM 0x00060000 /* external request input source mode */ +#define DMxCTR_RQM_FALLEDGE 0x00000000 /* - falling edge */ +#define DMxCTR_RQM_RISEEDGE 0x00020000 /* - rising edge */ +#define DMxCTR_RQM_LOLEVEL 0x00040000 /* - low level */ +#define DMxCTR_RQM_HILEVEL 0x00060000 /* - high level */ +#define DMxCTR_RQF 0x01000000 /* DMA transfer request flag */ +#define DMxCTR_XEND 0x80000000 /* DMA transfer end flag */ + +#define DMxSRC(N) __SYSREG(0xd2000004 + ((N) * 0x100), u32) /* control reg */ + +#define DMxDST(N) __SYSREG(0xd2000008 + ((N) * 0x100), u32) /* src addr reg */ + +#define DMxSIZ(N) __SYSREG(0xd200000c + ((N) * 0x100), u32) /* dest addr reg */ +#define DMxSIZ_CT 0x000fffff /* number of bytes to transfer */ + +#define DMxCYC(N) __SYSREG(0xd2000010 + ((N) * 0x100), u32) /* intermittent + * size reg */ +#define DMxCYC_CYC 0x000000ff /* number of interrmittent transfers -1 */ + +#define DM0IRQ 16 /* DMA channel 0 complete IRQ */ +#define DM1IRQ 17 /* DMA channel 1 complete IRQ */ +#define DM2IRQ 18 /* DMA channel 2 complete IRQ */ +#define DM3IRQ 19 /* DMA channel 3 complete IRQ */ + +#define DM0ICR GxICR(DM0IRQ) /* DMA channel 0 complete intr ctrl reg */ +#define DM1ICR GxICR(DM0IR1) /* DMA channel 1 complete intr ctrl reg */ +#define DM2ICR GxICR(DM0IR2) /* DMA channel 2 complete intr ctrl reg */ +#define DM3ICR GxICR(DM0IR3) /* DMA channel 3 complete intr ctrl reg */ + +#ifndef __ASSEMBLY__ + +struct mn10300_dmactl_regs { + u32 ctr; + const void *src; + void *dst; + u32 siz; + u32 cyc; +} __attribute__((aligned(0x100))); + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_DMACTL_REGS_H */ diff --git a/arch/mn10300/include/asm/elf.h b/arch/mn10300/include/asm/elf.h new file mode 100644 index 0000000..bf09f8b --- /dev/null +++ b/arch/mn10300/include/asm/elf.h @@ -0,0 +1,147 @@ +/* MN10300 ELF constant and register definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_ELF_H +#define _ASM_ELF_H + +#include <linux/utsname.h> +#include <asm/ptrace.h> +#include <asm/user.h> + +/* + * AM33 relocations + */ +#define R_MN10300_NONE 0 /* No reloc. */ +#define R_MN10300_32 1 /* Direct 32 bit. */ +#define R_MN10300_16 2 /* Direct 16 bit. */ +#define R_MN10300_8 3 /* Direct 8 bit. */ +#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +#define R_MN10300_24 9 /* Direct 24 bit. */ +#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ + +/* + * ELF register definitions.. + */ +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +#define ELF_NFPREG 32 +typedef float elf_fpreg_t; + +typedef struct { + elf_fpreg_t fpregs[ELF_NFPREG]; + u_int32_t fpcr; +} elf_fpregset_t; + +extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); + +/* + * This is used to ensure we don't load something for the wrong architecture + */ +#define elf_check_arch(x) \ + (((x)->e_machine == EM_CYGNUS_MN10300) || \ + ((x)->e_machine == EM_MN10300)) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_MN10300 + +/* + * ELF process initialiser + */ +#define ELF_PLAT_INIT(_r, load_addr) \ +do { \ + struct pt_regs *_ur = current->thread.uregs; \ + _ur->a3 = 0; _ur->a2 = 0; _ur->d3 = 0; _ur->d2 = 0; \ + _ur->mcvf = 0; _ur->mcrl = 0; _ur->mcrh = 0; _ur->mdrq = 0; \ + _ur->e1 = 0; _ur->e0 = 0; _ur->e7 = 0; _ur->e6 = 0; \ + _ur->e5 = 0; _ur->e4 = 0; _ur->e3 = 0; _ur->e2 = 0; \ + _ur->lar = 0; _ur->lir = 0; _ur->mdr = 0; \ + _ur->a1 = 0; _ur->a0 = 0; _ur->d1 = 0; _ur->d0 = 0; \ +} while (0) + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +/* + * This is the location that an ET_DYN program is loaded if exec'ed. Typical + * use of this is to invoke "./ld.so someprog" to test out a new version of + * the loader. We need to make sure that it is out of the way of the program + * that it will "exec", and that there is sufficient room for the brk. + * - must clear the VMALLOC area + */ +#define ELF_ET_DYN_BASE 0x04000000 + +/* + * regs is struct pt_regs, pr_reg is elf_gregset_t (which is + * now struct user_regs, they are different) + * - ELF_CORE_COPY_REGS has been guessed, and may be wrong + */ +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ +do { \ + pr_reg[0] = regs->a3; \ + pr_reg[1] = regs->a2; \ + pr_reg[2] = regs->d3; \ + pr_reg[3] = regs->d2; \ + pr_reg[4] = regs->mcvf; \ + pr_reg[5] = regs->mcrl; \ + pr_reg[6] = regs->mcrh; \ + pr_reg[7] = regs->mdrq; \ + pr_reg[8] = regs->e1; \ + pr_reg[9] = regs->e0; \ + pr_reg[10] = regs->e7; \ + pr_reg[11] = regs->e6; \ + pr_reg[12] = regs->e5; \ + pr_reg[13] = regs->e4; \ + pr_reg[14] = regs->e3; \ + pr_reg[15] = regs->e2; \ + pr_reg[16] = regs->sp; \ + pr_reg[17] = regs->lar; \ + pr_reg[18] = regs->lir; \ + pr_reg[19] = regs->mdr; \ + pr_reg[20] = regs->a1; \ + pr_reg[21] = regs->a0; \ + pr_reg[22] = regs->d1; \ + pr_reg[23] = regs->d0; \ + pr_reg[24] = regs->orig_d0; \ + pr_reg[25] = regs->epsw; \ + pr_reg[26] = regs->pc; \ +} while (0); + +/* + * This yields a mask that user programs can use to figure out what + * instruction set this CPU supports. This could be done in user space, + * but it's not easy, and we've already done it here. + */ +#define ELF_HWCAP (0) + +/* + * This yields a string that ld.so will use to load implementation + * specific libraries for optimization. This is more specific in + * intent than poking at uname or /proc/cpuinfo. + * + * For the moment, we have only optimizations for the Intel generations, + * but that could change... + */ +#define ELF_PLATFORM (NULL) + +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex) set_personality(PER_LINUX) +#endif + +#endif /* _ASM_ELF_H */ diff --git a/arch/mn10300/include/asm/emergency-restart.h b/arch/mn10300/include/asm/emergency-restart.h new file mode 100644 index 0000000..3711bd9 --- /dev/null +++ b/arch/mn10300/include/asm/emergency-restart.h @@ -0,0 +1 @@ +#include <asm-generic/emergency-restart.h> diff --git a/arch/mn10300/include/asm/errno.h b/arch/mn10300/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/arch/mn10300/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/arch/mn10300/include/asm/exceptions.h b/arch/mn10300/include/asm/exceptions.h new file mode 100644 index 0000000..fa16466 --- /dev/null +++ b/arch/mn10300/include/asm/exceptions.h @@ -0,0 +1,121 @@ +/* MN10300 Microcontroller core exceptions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_EXCEPTIONS_H +#define _ASM_EXCEPTIONS_H + +#include <linux/linkage.h> + +/* + * define the breakpoint instruction opcode to use + * - note that the JTAG unit steals 0xFF, so we want to avoid that if we can + * (can use 0xF7) + */ +#define GDBSTUB_BKPT 0xFF + +#ifndef __ASSEMBLY__ + +/* + * enumeration of exception codes (as extracted from TBR MSW) + */ +enum exception_code { + EXCEP_RESET = 0x000000, /* reset */ + + /* MMU exceptions */ + EXCEP_ITLBMISS = 0x000100, /* instruction TLB miss */ + EXCEP_DTLBMISS = 0x000108, /* data TLB miss */ + EXCEP_IAERROR = 0x000110, /* instruction address */ + EXCEP_DAERROR = 0x000118, /* data address */ + + /* system exceptions */ + EXCEP_TRAP = 0x000128, /* program interrupt (PI instruction) */ + EXCEP_ISTEP = 0x000130, /* single step */ + EXCEP_IBREAK = 0x000150, /* instruction breakpoint */ + EXCEP_OBREAK = 0x000158, /* operand breakpoint */ + EXCEP_PRIVINS = 0x000160, /* privileged instruction execution */ + EXCEP_UNIMPINS = 0x000168, /* unimplemented instruction execution */ + EXCEP_UNIMPEXINS = 0x000170, /* unimplemented extended instruction execution */ + EXCEP_MEMERR = 0x000178, /* illegal memory access */ + EXCEP_MISALIGN = 0x000180, /* misalignment */ + EXCEP_BUSERROR = 0x000188, /* bus error */ + EXCEP_ILLINSACC = 0x000190, /* illegal instruction access */ + EXCEP_ILLDATACC = 0x000198, /* illegal data access */ + EXCEP_IOINSACC = 0x0001a0, /* I/O space instruction access */ + EXCEP_PRIVINSACC = 0x0001a8, /* privileged space instruction access */ + EXCEP_PRIVDATACC = 0x0001b0, /* privileged space data access */ + EXCEP_DATINSACC = 0x0001b8, /* data space instruction access */ + EXCEP_DOUBLE_FAULT = 0x000200, /* double fault */ + + /* FPU exceptions */ + EXCEP_FPU_DISABLED = 0x0001c0, /* FPU disabled */ + EXCEP_FPU_UNIMPINS = 0x0001c8, /* FPU unimplemented operation */ + EXCEP_FPU_OPERATION = 0x0001d0, /* FPU operation */ + + /* interrupts */ + EXCEP_WDT = 0x000240, /* watchdog timer overflow */ + EXCEP_NMI = 0x000248, /* non-maskable interrupt */ + EXCEP_IRQ_LEVEL0 = 0x000280, /* level 0 maskable interrupt */ + EXCEP_IRQ_LEVEL1 = 0x000288, /* level 1 maskable interrupt */ + EXCEP_IRQ_LEVEL2 = 0x000290, /* level 2 maskable interrupt */ + EXCEP_IRQ_LEVEL3 = 0x000298, /* level 3 maskable interrupt */ + EXCEP_IRQ_LEVEL4 = 0x0002a0, /* level 4 maskable interrupt */ + EXCEP_IRQ_LEVEL5 = 0x0002a8, /* level 5 maskable interrupt */ + EXCEP_IRQ_LEVEL6 = 0x0002b0, /* level 6 maskable interrupt */ + + /* system calls */ + EXCEP_SYSCALL0 = 0x000300, /* system call 0 */ + EXCEP_SYSCALL1 = 0x000308, /* system call 1 */ + EXCEP_SYSCALL2 = 0x000310, /* system call 2 */ + EXCEP_SYSCALL3 = 0x000318, /* system call 3 */ + EXCEP_SYSCALL4 = 0x000320, /* system call 4 */ + EXCEP_SYSCALL5 = 0x000328, /* system call 5 */ + EXCEP_SYSCALL6 = 0x000330, /* system call 6 */ + EXCEP_SYSCALL7 = 0x000338, /* system call 7 */ + EXCEP_SYSCALL8 = 0x000340, /* system call 8 */ + EXCEP_SYSCALL9 = 0x000348, /* system call 9 */ + EXCEP_SYSCALL10 = 0x000350, /* system call 10 */ + EXCEP_SYSCALL11 = 0x000358, /* system call 11 */ + EXCEP_SYSCALL12 = 0x000360, /* system call 12 */ + EXCEP_SYSCALL13 = 0x000368, /* system call 13 */ + EXCEP_SYSCALL14 = 0x000370, /* system call 14 */ + EXCEP_SYSCALL15 = 0x000378, /* system call 15 */ +}; + +extern void __set_intr_stub(enum exception_code code, void *handler); +extern void set_intr_stub(enum exception_code code, void *handler); +extern void set_jtag_stub(enum exception_code code, void *handler); + +struct pt_regs; + +extern asmlinkage void __common_exception(void); +extern asmlinkage void itlb_miss(void); +extern asmlinkage void dtlb_miss(void); +extern asmlinkage void itlb_aerror(void); +extern asmlinkage void dtlb_aerror(void); +extern asmlinkage void raw_bus_error(void); +extern asmlinkage void double_fault(void); +extern asmlinkage int system_call(struct pt_regs *); +extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code); +extern asmlinkage void nmi(struct pt_regs *, enum exception_code); +extern asmlinkage void uninitialised_exception(struct pt_regs *, + enum exception_code); +extern asmlinkage void irq_handler(void); +extern asmlinkage void profile_handler(void); +extern asmlinkage void nmi_handler(void); +extern asmlinkage void misalignment(struct pt_regs *, enum exception_code); + +extern void die(const char *, struct pt_regs *, enum exception_code) + ATTRIB_NORET; + +extern int die_if_no_fixup(const char *, struct pt_regs *, enum exception_code); + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_EXCEPTIONS_H */ diff --git a/arch/mn10300/include/asm/fb.h b/arch/mn10300/include/asm/fb.h new file mode 100644 index 0000000..697b24a --- /dev/null +++ b/arch/mn10300/include/asm/fb.h @@ -0,0 +1,23 @@ +/* MN10300 Frame buffer stuff + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_FB_H +#define _ASM_FB_H + +#include <linux/fb.h> + +#define fb_pgprotect(...) do {} while (0) + +static inline int fb_is_primary_device(struct fb_info *info) +{ + return 0; +} + +#endif /* _ASM_FB_H */ diff --git a/arch/mn10300/include/asm/fcntl.h b/arch/mn10300/include/asm/fcntl.h new file mode 100644 index 0000000..46ab12d --- /dev/null +++ b/arch/mn10300/include/asm/fcntl.h @@ -0,0 +1 @@ +#include <asm-generic/fcntl.h> diff --git a/arch/mn10300/include/asm/fpu.h b/arch/mn10300/include/asm/fpu.h new file mode 100644 index 0000000..64a2b83 --- /dev/null +++ b/arch/mn10300/include/asm/fpu.h @@ -0,0 +1,85 @@ +/* MN10300 FPU definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * Derived from include/asm-i386/i387.h: Copyright (C) 1994 Linus Torvalds + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_FPU_H +#define _ASM_FPU_H + +#include <asm/processor.h> +#include <asm/sigcontext.h> +#include <asm/user.h> + +#ifdef __KERNEL__ + +/* the task that owns the FPU state */ +extern struct task_struct *fpu_state_owner; + +#define set_using_fpu(tsk) \ +do { \ + (tsk)->thread.fpu_flags |= THREAD_USING_FPU; \ +} while (0) + +#define clear_using_fpu(tsk) \ +do { \ + (tsk)->thread.fpu_flags &= ~THREAD_USING_FPU; \ +} while (0) + +#define is_using_fpu(tsk) ((tsk)->thread.fpu_flags & THREAD_USING_FPU) + +#define unlazy_fpu(tsk) \ +do { \ + preempt_disable(); \ + if (fpu_state_owner == (tsk)) \ + fpu_save(&tsk->thread.fpu_state); \ + preempt_enable(); \ +} while (0) + +#define exit_fpu() \ +do { \ + struct task_struct *__tsk = current; \ + preempt_disable(); \ + if (fpu_state_owner == __tsk) \ + fpu_state_owner = NULL; \ + preempt_enable(); \ +} while (0) + +#define flush_fpu() \ +do { \ + struct task_struct *__tsk = current; \ + preempt_disable(); \ + if (fpu_state_owner == __tsk) { \ + fpu_state_owner = NULL; \ + __tsk->thread.uregs->epsw &= ~EPSW_FE; \ + } \ + preempt_enable(); \ + clear_using_fpu(__tsk); \ +} while (0) + +extern asmlinkage void fpu_init_state(void); +extern asmlinkage void fpu_kill_state(struct task_struct *); +extern asmlinkage void fpu_disabled(struct pt_regs *, enum exception_code); +extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code); + +#ifdef CONFIG_FPU +extern asmlinkage void fpu_save(struct fpu_state_struct *); +extern asmlinkage void fpu_restore(struct fpu_state_struct *); +#else +#define fpu_save(a) +#define fpu_restore(a) +#endif /* CONFIG_FPU */ + +/* + * signal frame handlers + */ +extern int fpu_setup_sigcontext(struct fpucontext *buf); +extern int fpu_restore_sigcontext(struct fpucontext *buf); + +#endif /* __KERNEL__ */ +#endif /* _ASM_FPU_H */ diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc new file mode 100644 index 0000000..5b1949b --- /dev/null +++ b/arch/mn10300/include/asm/frame.inc @@ -0,0 +1,91 @@ +/* MN10300 Microcontroller core system register definitions -*- asm -*- + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_FRAME_INC +#define _ASM_FRAME_INC + +#ifndef __ASSEMBLY__ +#error not for use in C files +#endif + +#ifndef __ASM_OFFSETS_H__ +#include <asm/asm-offsets.h> +#endif + +#define pi break + +#define fp a3 + +############################################################################### +# +# build a stack frame from the registers +# - the caller has subtracted 4 from SP before coming here +# +############################################################################### +.macro SAVE_ALL + add -4,sp # next exception frame ptr save area + movm [other],(sp) + mov usp,a1 + mov a1,(sp) # USP in MOVM[other] dummy slot + movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp) + mov sp,fp # FRAME pointer in A3 + add -12,sp # allow for calls to be made + mov (__frame),a1 + mov a1,(REG_NEXT,fp) + mov fp,(__frame) + + and ~EPSW_FE,epsw # disable the FPU inside the kernel + + # we may be holding current in E2 +#ifdef CONFIG_MN10300_CURRENT_IN_E2 + mov (__current),e2 +#endif +.endm + +############################################################################### +# +# restore the registers from a stack frame +# +############################################################################### +.macro RESTORE_ALL + # peel back the stack to the calling frame + # - this permits execve() to discard extra frames due to kernel syscalls + mov (__frame),fp + mov fp,sp + mov (REG_NEXT,fp),d0 # userspace has regs->next == 0 + mov d0,(__frame) + +#ifndef CONFIG_MN10300_USING_JTAG + mov (REG_EPSW,fp),d0 + btst EPSW_T,d0 + beq 99f + + or EPSW_NMID,epsw + movhu (DCR),d1 + or 0x0001, d1 + movhu d1,(DCR) + +99: +#endif + movm (sp),[d2,d3,a2,a3,exreg0,exreg1,exother] + + # must restore usp even if returning to kernel space, + # when CONFIG_PREEMPT is enabled. + mov (sp),a1 # USP in MOVM[other] dummy slot + mov a1,usp + + movm (sp),[other] + add 8,sp + rti + +.endm + + +#endif /* _ASM_FRAME_INC */ diff --git a/arch/mn10300/include/asm/ftrace.h b/arch/mn10300/include/asm/ftrace.h new file mode 100644 index 0000000..40a8c17 --- /dev/null +++ b/arch/mn10300/include/asm/ftrace.h @@ -0,0 +1 @@ +/* empty */ diff --git a/arch/mn10300/include/asm/futex.h b/arch/mn10300/include/asm/futex.h new file mode 100644 index 0000000..0b74582 --- /dev/null +++ b/arch/mn10300/include/asm/futex.h @@ -0,0 +1 @@ +#include <asm-generic/futex.h> diff --git a/arch/mn10300/include/asm/gdb-stub.h b/arch/mn10300/include/asm/gdb-stub.h new file mode 100644 index 0000000..e5a6368 --- /dev/null +++ b/arch/mn10300/include/asm/gdb-stub.h @@ -0,0 +1,183 @@ +/* MN10300 Kernel GDB stub definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_GDB_STUB_H +#define _ASM_GDB_STUB_H + +#include <asm/exceptions.h> + +/* + * register ID numbers in GDB remote protocol + */ + +#define GDB_REGID_PC 9 +#define GDB_REGID_FP 7 +#define GDB_REGID_SP 8 + +/* + * virtual stack layout for the GDB exception handler + */ +#define NUMREGS 64 + +#define GDB_FR_D0 (0 * 4) +#define GDB_FR_D1 (1 * 4) +#define GDB_FR_D2 (2 * 4) +#define GDB_FR_D3 (3 * 4) +#define GDB_FR_A0 (4 * 4) +#define GDB_FR_A1 (5 * 4) +#define GDB_FR_A2 (6 * 4) +#define GDB_FR_A3 (7 * 4) + +#define GDB_FR_SP (8 * 4) +#define GDB_FR_PC (9 * 4) +#define GDB_FR_MDR (10 * 4) +#define GDB_FR_EPSW (11 * 4) +#define GDB_FR_LIR (12 * 4) +#define GDB_FR_LAR (13 * 4) +#define GDB_FR_MDRQ (14 * 4) + +#define GDB_FR_E0 (15 * 4) +#define GDB_FR_E1 (16 * 4) +#define GDB_FR_E2 (17 * 4) +#define GDB_FR_E3 (18 * 4) +#define GDB_FR_E4 (19 * 4) +#define GDB_FR_E5 (20 * 4) +#define GDB_FR_E6 (21 * 4) +#define GDB_FR_E7 (22 * 4) + +#define GDB_FR_SSP (23 * 4) +#define GDB_FR_MSP (24 * 4) +#define GDB_FR_USP (25 * 4) +#define GDB_FR_MCRH (26 * 4) +#define GDB_FR_MCRL (27 * 4) +#define GDB_FR_MCVF (28 * 4) + +#define GDB_FR_FPCR (29 * 4) +#define GDB_FR_DUMMY0 (30 * 4) +#define GDB_FR_DUMMY1 (31 * 4) + +#define GDB_FR_FS0 (32 * 4) + +#define GDB_FR_SIZE (NUMREGS * 4) + +#ifndef __ASSEMBLY__ + +/* + * This is the same as above, but for the high-level + * part of the GDB stub. + */ + +struct gdb_regs { + /* saved main processor registers */ + u32 d0, d1, d2, d3, a0, a1, a2, a3; + u32 sp, pc, mdr, epsw, lir, lar, mdrq; + u32 e0, e1, e2, e3, e4, e5, e6, e7; + u32 ssp, msp, usp, mcrh, mcrl, mcvf; + + /* saved floating point registers */ + u32 fpcr, _dummy0, _dummy1; + u32 fs0, fs1, fs2, fs3, fs4, fs5, fs6, fs7; + u32 fs8, fs9, fs10, fs11, fs12, fs13, fs14, fs15; + u32 fs16, fs17, fs18, fs19, fs20, fs21, fs22, fs23; + u32 fs24, fs25, fs26, fs27, fs28, fs29, fs30, fs31; +}; + +/* + * Prototypes + */ +extern void show_registers_only(struct pt_regs *regs); + +extern asmlinkage void gdbstub_init(void); +extern asmlinkage void gdbstub_exit(int status); +extern asmlinkage void gdbstub_io_init(void); +extern asmlinkage void gdbstub_io_set_baud(unsigned baud); +extern asmlinkage int gdbstub_io_rx_char(unsigned char *_ch, int nonblock); +extern asmlinkage void gdbstub_io_tx_char(unsigned char ch); +extern asmlinkage void gdbstub_io_tx_flush(void); + +extern asmlinkage void gdbstub_io_rx_handler(void); +extern asmlinkage void gdbstub_rx_irq(struct pt_regs *, enum exception_code); +extern asmlinkage int gdbstub_intercept(struct pt_regs *, enum exception_code); +extern asmlinkage void gdbstub_exception(struct pt_regs *, enum exception_code); +extern asmlinkage void __gdbstub_bug_trap(void); +extern asmlinkage void __gdbstub_pause(void); +extern asmlinkage void start_kernel(void); + +#ifndef CONFIG_MN10300_CACHE_DISABLED +extern asmlinkage void gdbstub_purge_cache(void); +#else +#define gdbstub_purge_cache() do {} while (0) +#endif + +/* Used to prevent crashes in memory access */ +extern asmlinkage int gdbstub_read_byte(const u8 *, u8 *); +extern asmlinkage int gdbstub_read_word(const u8 *, u8 *); +extern asmlinkage int gdbstub_read_dword(const u8 *, u8 *); +extern asmlinkage int gdbstub_write_byte(u32, u8 *); +extern asmlinkage int gdbstub_write_word(u32, u8 *); +extern asmlinkage int gdbstub_write_dword(u32, u8 *); + +extern asmlinkage void gdbstub_read_byte_guard(void); +extern asmlinkage void gdbstub_read_byte_cont(void); +extern asmlinkage void gdbstub_read_word_guard(void); +extern asmlinkage void gdbstub_read_word_cont(void); +extern asmlinkage void gdbstub_read_dword_guard(void); +extern asmlinkage void gdbstub_read_dword_cont(void); +extern asmlinkage void gdbstub_write_byte_guard(void); +extern asmlinkage void gdbstub_write_byte_cont(void); +extern asmlinkage void gdbstub_write_word_guard(void); +extern asmlinkage void gdbstub_write_word_cont(void); +extern asmlinkage void gdbstub_write_dword_guard(void); +extern asmlinkage void gdbstub_write_dword_cont(void); + +extern u8 gdbstub_rx_buffer[PAGE_SIZE]; +extern u32 gdbstub_rx_inp; +extern u32 gdbstub_rx_outp; +extern u8 gdbstub_rx_overflow; +extern u8 gdbstub_busy; +extern u8 gdbstub_rx_unget; + +#ifdef CONFIG_GDBSTUB_DEBUGGING +extern void gdbstub_printk(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); +#else +static inline __attribute__((format(printf, 1, 2))) +void gdbstub_printk(const char *fmt, ...) +{ +} +#endif + +#ifdef CONFIG_GDBSTUB_DEBUG_ENTRY +#define gdbstub_entry(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__) +#else +#define gdbstub_entry(FMT, ...) ({ 0; }) +#endif + +#ifdef CONFIG_GDBSTUB_DEBUG_PROTOCOL +#define gdbstub_proto(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__) +#else +#define gdbstub_proto(FMT, ...) ({ 0; }) +#endif + +#ifdef CONFIG_GDBSTUB_DEBUG_IO +#define gdbstub_io(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__) +#else +#define gdbstub_io(FMT, ...) ({ 0; }) +#endif + +#ifdef CONFIG_GDBSTUB_DEBUG_BREAKPOINT +#define gdbstub_bkpt(FMT, ...) gdbstub_printk(FMT, ##__VA_ARGS__) +#else +#define gdbstub_bkpt(FMT, ...) ({ 0; }) +#endif + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_GDB_STUB_H */ diff --git a/arch/mn10300/include/asm/hardirq.h b/arch/mn10300/include/asm/hardirq.h new file mode 100644 index 0000000..54d9501 --- /dev/null +++ b/arch/mn10300/include/asm/hardirq.h @@ -0,0 +1,48 @@ +/* MN10300 Hardware IRQ statistics and management + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Modified by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_HARDIRQ_H +#define _ASM_HARDIRQ_H + +#include <linux/threads.h> +#include <linux/irq.h> +#include <asm/exceptions.h> + +/* assembly code in softirq.h is sensitive to the offsets of these fields */ +typedef struct { + unsigned int __softirq_pending; + unsigned long idle_timestamp; + unsigned int __nmi_count; /* arch dependent */ + unsigned int __irq_count; /* arch dependent */ +} ____cacheline_aligned irq_cpustat_t; + +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ + +extern void ack_bad_irq(int irq); + +/* + * manipulate stubs in the MN10300 CPU Trap/Interrupt Vector table + * - these should jump to __common_exception in entry.S unless there's a good + * reason to do otherwise (see trap_preinit() in traps.c) + */ +typedef void (*intr_stub_fnx)(struct pt_regs *regs, + enum exception_code intcode); + +/* + * manipulate pointers in the Exception table (see entry.S) + * - these are indexed by decoding the lower 24 bits of the TBR register + * - note that the MN103E010 doesn't always trap through the correct vector, + * but does always set the TBR correctly + */ +extern asmlinkage void set_excp_vector(enum exception_code code, + intr_stub_fnx handler); + +#endif /* _ASM_HARDIRQ_H */ diff --git a/arch/mn10300/include/asm/highmem.h b/arch/mn10300/include/asm/highmem.h new file mode 100644 index 0000000..90f2abb --- /dev/null +++ b/arch/mn10300/include/asm/highmem.h @@ -0,0 +1,116 @@ +/* MN10300 Virtual kernel memory mappings for high memory + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from include/asm-i386/highmem.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_HIGHMEM_H +#define _ASM_HIGHMEM_H + +#ifdef __KERNEL__ + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/highmem.h> +#include <asm/kmap_types.h> +#include <asm/pgtable.h> + +/* undef for production */ +#undef HIGHMEM_DEBUG + +/* declarations for highmem.c */ +extern unsigned long highstart_pfn, highend_pfn; + +extern pte_t *kmap_pte; +extern pgprot_t kmap_prot; +extern pte_t *pkmap_page_table; + +extern void __init kmap_init(void); + +/* + * Right now we initialize only a single pte table. It can be extended + * easily, subsequent pte tables have to be allocated in one physical + * chunk of RAM. + */ +#define PKMAP_BASE 0xfe000000UL +#define LAST_PKMAP 1024 +#define LAST_PKMAP_MASK (LAST_PKMAP - 1) +#define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT) +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) + +extern unsigned long kmap_high(struct page *page); +extern void kunmap_high(struct page *page); + +static inline unsigned long kmap(struct page *page) +{ + if (in_interrupt()) + BUG(); + if (page < highmem_start_page) + return page_address(page); + return kmap_high(page); +} + +static inline void kunmap(struct page *page) +{ + if (in_interrupt()) + BUG(); + if (page < highmem_start_page) + return; + kunmap_high(page); +} + +/* + * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap + * gives a more generic (and caching) interface. But kmap_atomic can + * be used in IRQ contexts, so in some (very limited) cases we need + * it. + */ +static inline unsigned long kmap_atomic(struct page *page, enum km_type type) +{ + enum fixed_addresses idx; + unsigned long vaddr; + + if (page < highmem_start_page) + return page_address(page); + + debug_kmap_atomic(type); + idx = type + KM_TYPE_NR * smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#if HIGHMEM_DEBUG + if (!pte_none(*(kmap_pte - idx))) + BUG(); +#endif + set_pte(kmap_pte - idx, mk_pte(page, kmap_prot)); + __flush_tlb_one(vaddr); + + return vaddr; +} + +static inline void kunmap_atomic(unsigned long vaddr, enum km_type type) +{ +#if HIGHMEM_DEBUG + enum fixed_addresses idx = type + KM_TYPE_NR * smp_processor_id(); + + if (vaddr < FIXADDR_START) /* FIXME */ + return; + + if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)) + BUG(); + + /* + * force other mappings to Oops if they'll try to access + * this pte without first remap it + */ + pte_clear(kmap_pte - idx); + __flush_tlb_one(vaddr); +#endif +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_HIGHMEM_H */ diff --git a/arch/mn10300/include/asm/hw_irq.h b/arch/mn10300/include/asm/hw_irq.h new file mode 100644 index 0000000..7061990 --- /dev/null +++ b/arch/mn10300/include/asm/hw_irq.h @@ -0,0 +1,14 @@ +/* MN10300 Hardware interrupt definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_HW_IRQ_H +#define _ASM_HW_IRQ_H + +#endif /* _ASM_HW_IRQ_H */ diff --git a/arch/mn10300/include/asm/intctl-regs.h b/arch/mn10300/include/asm/intctl-regs.h new file mode 100644 index 0000000..ba544c7 --- /dev/null +++ b/arch/mn10300/include/asm/intctl-regs.h @@ -0,0 +1,73 @@ +/* MN10300 On-board interrupt controller registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_INTCTL_REGS_H +#define _ASM_INTCTL_REGS_H + +#include <asm/cpu-regs.h> + +#ifdef __KERNEL__ + +/* interrupt controller registers */ +#define GxICR(X) __SYSREG(0xd4000000 + (X) * 4, u16) /* group irq ctrl regs */ + +#define IAGR __SYSREG(0xd4000100, u16) /* intr acceptance group reg */ +#define IAGR_GN 0x00fc /* group number register + * (documentation _has_ to be wrong) + */ + +#define EXTMD __SYSREG(0xd4000200, u16) /* external pin intr spec reg */ +#define GET_XIRQ_TRIGGER(X) ((EXTMD >> ((X) * 2)) & 3) + +#define SET_XIRQ_TRIGGER(X,Y) \ +do { \ + u16 x = EXTMD; \ + x &= ~(3 << ((X) * 2)); \ + x |= ((Y) & 3) << ((X) * 2); \ + EXTMD = x; \ +} while (0) + +#define XIRQ_TRIGGER_LOWLEVEL 0 +#define XIRQ_TRIGGER_HILEVEL 1 +#define XIRQ_TRIGGER_NEGEDGE 2 +#define XIRQ_TRIGGER_POSEDGE 3 + +/* non-maskable interrupt control */ +#define NMIIRQ 0 +#define NMICR GxICR(NMIIRQ) /* NMI control register */ +#define NMICR_NMIF 0x0001 /* NMI pin interrupt flag */ +#define NMICR_WDIF 0x0002 /* watchdog timer overflow flag */ +#define NMICR_ABUSERR 0x0008 /* async bus error flag */ + +/* maskable interrupt control */ +#define GxICR_DETECT 0x0001 /* interrupt detect flag */ +#define GxICR_REQUEST 0x0010 /* interrupt request flag */ +#define GxICR_ENABLE 0x0100 /* interrupt enable flag */ +#define GxICR_LEVEL 0x7000 /* interrupt priority level */ +#define GxICR_LEVEL_0 0x0000 /* - level 0 */ +#define GxICR_LEVEL_1 0x1000 /* - level 1 */ +#define GxICR_LEVEL_2 0x2000 /* - level 2 */ +#define GxICR_LEVEL_3 0x3000 /* - level 3 */ +#define GxICR_LEVEL_4 0x4000 /* - level 4 */ +#define GxICR_LEVEL_5 0x5000 /* - level 5 */ +#define GxICR_LEVEL_6 0x6000 /* - level 6 */ +#define GxICR_LEVEL_SHIFT 12 + +#ifndef __ASSEMBLY__ +extern void set_intr_level(int irq, u16 level); +extern void set_intr_postackable(int irq); +#endif + +/* external interrupts */ +#define XIRQxICR(X) GxICR((X)) /* external interrupt control regs */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_INTCTL_REGS_H */ diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h new file mode 100644 index 0000000..c1a4119 --- /dev/null +++ b/arch/mn10300/include/asm/io.h @@ -0,0 +1,301 @@ +/* MN10300 I/O port emulation and memory-mapped I/O + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_IO_H +#define _ASM_IO_H + +#include <asm/page.h> /* I/O is all done through memory accesses */ +#include <asm/cpu-regs.h> +#include <asm/cacheflush.h> + +#define mmiowb() do {} while (0) + +/*****************************************************************************/ +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + */ +static inline u8 readb(const volatile void __iomem *addr) +{ + return *(const volatile u8 *) addr; +} + +static inline u16 readw(const volatile void __iomem *addr) +{ + return *(const volatile u16 *) addr; +} + +static inline u32 readl(const volatile void __iomem *addr) +{ + return *(const volatile u32 *) addr; +} + +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl + +#define readb_relaxed readb +#define readw_relaxed readw +#define readl_relaxed readl + +static inline void writeb(u8 b, volatile void __iomem *addr) +{ + *(volatile u8 *) addr = b; +} + +static inline void writew(u16 b, volatile void __iomem *addr) +{ + *(volatile u16 *) addr = b; +} + +static inline void writel(u32 b, volatile void __iomem *addr) +{ + *(volatile u32 *) addr = b; +} + +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel + +/*****************************************************************************/ +/* + * traditional input/output functions + */ +static inline u8 inb_local(unsigned long addr) +{ + return readb((volatile void __iomem *) addr); +} + +static inline void outb_local(u8 b, unsigned long addr) +{ + return writeb(b, (volatile void __iomem *) addr); +} + +static inline u8 inb(unsigned long addr) +{ + return readb((volatile void __iomem *) addr); +} + +static inline u16 inw(unsigned long addr) +{ + return readw((volatile void __iomem *) addr); +} + +static inline u32 inl(unsigned long addr) +{ + return readl((volatile void __iomem *) addr); +} + +static inline void outb(u8 b, unsigned long addr) +{ + return writeb(b, (volatile void __iomem *) addr); +} + +static inline void outw(u16 b, unsigned long addr) +{ + return writew(b, (volatile void __iomem *) addr); +} + +static inline void outl(u32 b, unsigned long addr) +{ + return writel(b, (volatile void __iomem *) addr); +} + +#define inb_p(addr) inb(addr) +#define inw_p(addr) inw(addr) +#define inl_p(addr) inl(addr) +#define outb_p(x, addr) outb((x), (addr)) +#define outw_p(x, addr) outw((x), (addr)) +#define outl_p(x, addr) outl((x), (addr)) + +static inline void insb(unsigned long addr, void *buffer, int count) +{ + if (count) { + u8 *buf = buffer; + do { + u8 x = inb(addr); + *buf++ = x; + } while (--count); + } +} + +static inline void insw(unsigned long addr, void *buffer, int count) +{ + if (count) { + u16 *buf = buffer; + do { + u16 x = inw(addr); + *buf++ = x; + } while (--count); + } +} + +static inline void insl(unsigned long addr, void *buffer, int count) +{ + if (count) { + u32 *buf = buffer; + do { + u32 x = inl(addr); + *buf++ = x; + } while (--count); + } +} + +static inline void outsb(unsigned long addr, const void *buffer, int count) +{ + if (count) { + const u8 *buf = buffer; + do { + outb(*buf++, addr); + } while (--count); + } +} + +static inline void outsw(unsigned long addr, const void *buffer, int count) +{ + if (count) { + const u16 *buf = buffer; + do { + outw(*buf++, addr); + } while (--count); + } +} + +extern void __outsl(unsigned long addr, const void *buffer, int count); +static inline void outsl(unsigned long addr, const void *buffer, int count) +{ + if ((unsigned long) buffer & 0x3) + return __outsl(addr, buffer, count); + + if (count) { + const u32 *buf = buffer; + do { + outl(*buf++, addr); + } while (--count); + } +} + +#define ioread8(addr) readb(addr) +#define ioread16(addr) readw(addr) +#define ioread32(addr) readl(addr) + +#define iowrite8(v, addr) writeb((v), (addr)) +#define iowrite16(v, addr) writew((v), (addr)) +#define iowrite32(v, addr) writel((v), (addr)) + +#define ioread8_rep(p, dst, count) \ + insb((unsigned long) (p), (dst), (count)) +#define ioread16_rep(p, dst, count) \ + insw((unsigned long) (p), (dst), (count)) +#define ioread32_rep(p, dst, count) \ + insl((unsigned long) (p), (dst), (count)) + +#define iowrite8_rep(p, src, count) \ + outsb((unsigned long) (p), (src), (count)) +#define iowrite16_rep(p, src, count) \ + outsw((unsigned long) (p), (src), (count)) +#define iowrite32_rep(p, src, count) \ + outsl((unsigned long) (p), (src), (count)) + + +#define IO_SPACE_LIMIT 0xffffffff + +#ifdef __KERNEL__ + +#include <linux/vmalloc.h> +#define __io_virt(x) ((void *) (x)) + +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ +struct pci_dev; +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); +static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) +{ +} + +/* + * Change virtual addresses to physical addresses and vv. + * These are pretty trivial + */ +static inline unsigned long virt_to_phys(volatile void *address) +{ + return __pa(address); +} + +static inline void *phys_to_virt(unsigned long address) +{ + return __va(address); +} + +/* + * Change "struct page" to physical address. + */ +static inline void *__ioremap(unsigned long offset, unsigned long size, + unsigned long flags) +{ + return (void *) offset; +} + +static inline void *ioremap(unsigned long offset, unsigned long size) +{ + return (void *) offset; +} + +/* + * This one maps high address device memory and turns off caching for that + * area. it's useful if some control registers are in such an area and write + * combining or read caching is not desirable: + */ +static inline void *ioremap_nocache(unsigned long offset, unsigned long size) +{ + return (void *) (offset | 0x20000000); +} + +#define ioremap_wc ioremap_nocache + +static inline void iounmap(void *addr) +{ +} + +static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return (void __iomem *) port; +} + +static inline void ioport_unmap(void __iomem *p) +{ +} + +#define xlate_dev_kmem_ptr(p) ((void *) (p)) +#define xlate_dev_mem_ptr(p) ((void *) (p)) + +/* + * PCI bus iomem addresses must be in the region 0x80000000-0x9fffffff + */ +static inline unsigned long virt_to_bus(volatile void *address) +{ + return ((unsigned long) address) & ~0x20000000; +} + +static inline void *bus_to_virt(unsigned long address) +{ + return (void *) address; +} + +#define page_to_bus page_to_phys + +#define memset_io(a, b, c) memset(__io_virt(a), (b), (c)) +#define memcpy_fromio(a, b, c) memcpy((a), __io_virt(b), (c)) +#define memcpy_toio(a, b, c) memcpy(__io_virt(a), (b), (c)) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_IO_H */ diff --git a/arch/mn10300/include/asm/ioctl.h b/arch/mn10300/include/asm/ioctl.h new file mode 100644 index 0000000..b279fe0 --- /dev/null +++ b/arch/mn10300/include/asm/ioctl.h @@ -0,0 +1 @@ +#include <asm-generic/ioctl.h> diff --git a/arch/mn10300/include/asm/ioctls.h b/arch/mn10300/include/asm/ioctls.h new file mode 100644 index 0000000..dcbfb45 --- /dev/null +++ b/arch/mn10300/include/asm/ioctls.h @@ -0,0 +1,88 @@ +#ifndef _ASM_IOCTLS_H +#define _ASM_IOCTLS_H + +#include <asm/ioctl.h> + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TCGETS2 _IOR('T', 0x2A, struct termios2) +#define TCSETS2 _IOW('T', 0x2B, struct termios2) +#define TCSETSW2 _IOW('T', 0x2C, struct termios2) +#define TCSETSF2 _IOW('T', 0x2D, struct termios2) +#define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number + * (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ + +#define FIONCLEX 0x5450 +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ +#define FIOQSIZE 0x5460 + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* _ASM_IOCTLS_H */ diff --git a/arch/mn10300/include/asm/ipc.h b/arch/mn10300/include/asm/ipc.h new file mode 100644 index 0000000..a46e3d9 --- /dev/null +++ b/arch/mn10300/include/asm/ipc.h @@ -0,0 +1 @@ +#include <asm-generic/ipc.h> diff --git a/arch/mn10300/include/asm/ipcbuf.h b/arch/mn10300/include/asm/ipcbuf.h new file mode 100644 index 0000000..f6f63d4 --- /dev/null +++ b/arch/mn10300/include/asm/ipcbuf.h @@ -0,0 +1,29 @@ +#ifndef _ASM_IPCBUF_H +#define _ASM_IPCBUF_H + +/* + * The ipc64_perm structure for MN10300 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* _ASM_IPCBUF_H */ diff --git a/arch/mn10300/include/asm/irq.h b/arch/mn10300/include/asm/irq.h new file mode 100644 index 0000000..25c045d --- /dev/null +++ b/arch/mn10300/include/asm/irq.h @@ -0,0 +1,32 @@ +/* MN10300 Hardware interrupt definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Modified by David Howells (dhowells@redhat.com) + * - Derived from include/asm-i386/irq.h: + * - (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_IRQ_H +#define _ASM_IRQ_H + +#include <asm/intctl-regs.h> +#include <asm/reset-regs.h> +#include <proc/irq.h> + +/* this number is used when no interrupt has been assigned */ +#define NO_IRQ INT_MAX + +/* hardware irq numbers */ +#define NR_IRQS GxICR_NUM_IRQS + +/* external hardware irq numbers */ +#define NR_XIRQS GxICR_NUM_XIRQS + +#define irq_canonicalize(IRQ) (IRQ) + +#endif /* _ASM_IRQ_H */ diff --git a/arch/mn10300/include/asm/irq_regs.h b/arch/mn10300/include/asm/irq_regs.h new file mode 100644 index 0000000..a848cd2 --- /dev/null +++ b/arch/mn10300/include/asm/irq_regs.h @@ -0,0 +1,24 @@ +/* MN10300 IRQ registers pointer definition + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_IRQ_REGS_H +#define _ASM_IRQ_REGS_H + +/* + * Per-cpu current frame pointer - the location of the last exception frame on + * the stack + */ +#define ARCH_HAS_OWN_IRQ_REGS + +#ifndef __ASSEMBLY__ +#define get_irq_regs() (__frame) +#endif + +#endif /* _ASM_IRQ_REGS_H */ diff --git a/arch/mn10300/include/asm/kdebug.h b/arch/mn10300/include/asm/kdebug.h new file mode 100644 index 0000000..0f47e11 --- /dev/null +++ b/arch/mn10300/include/asm/kdebug.h @@ -0,0 +1,22 @@ +/* MN10300 In-kernel death knells + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_KDEBUG_H +#define _ASM_KDEBUG_H + +/* Grossly misnamed. */ +enum die_val { + DIE_OOPS = 1, + DIE_BREAKPOINT, + DIE_GPF, +}; + +#endif /* _ASM_KDEBUG_H */ diff --git a/arch/mn10300/include/asm/kmap_types.h b/arch/mn10300/include/asm/kmap_types.h new file mode 100644 index 0000000..3398f9f --- /dev/null +++ b/arch/mn10300/include/asm/kmap_types.h @@ -0,0 +1,31 @@ +/* MN10300 kmap_atomic() slot IDs + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#endif /* _ASM_KMAP_TYPES_H */ diff --git a/arch/mn10300/include/asm/kprobes.h b/arch/mn10300/include/asm/kprobes.h new file mode 100644 index 0000000..c800b59 --- /dev/null +++ b/arch/mn10300/include/asm/kprobes.h @@ -0,0 +1,50 @@ +/* MN10300 Kernel Probes support + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by Mark Salter (msalter@redhat.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public Licence as published by + * the Free Software Foundation; either version 2 of the Licence, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public Licence for more details. + * + * You should have received a copy of the GNU General Public Licence + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +#ifndef _ASM_KPROBES_H +#define _ASM_KPROBES_H + +#include <linux/types.h> +#include <linux/ptrace.h> + +struct kprobe; + +typedef unsigned char kprobe_opcode_t; +#define BREAKPOINT_INSTRUCTION 0xff +#define MAX_INSN_SIZE 8 +#define MAX_STACK_SIZE 128 + +/* Architecture specific copy of original instruction */ +struct arch_specific_insn { + /* copy of original instruction + */ + kprobe_opcode_t insn[MAX_INSN_SIZE]; +}; + +extern const int kretprobe_blacklist_size; + +extern int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); + +#define flush_insn_slot(p) do {} while (0) + +extern void arch_remove_kprobe(struct kprobe *p); + +#endif /* _ASM_KPROBES_H */ diff --git a/arch/mn10300/include/asm/linkage.h b/arch/mn10300/include/asm/linkage.h new file mode 100644 index 0000000..dda3002 --- /dev/null +++ b/arch/mn10300/include/asm/linkage.h @@ -0,0 +1,20 @@ +/* MN10300 Linkage and calling-convention overrides + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_LINKAGE_H +#define _ASM_LINKAGE_H + +/* don't override anything */ +#define asmlinkage + +#define __ALIGN .align 4,0xcb +#define __ALIGN_STR ".align 4,0xcb" + +#endif diff --git a/arch/mn10300/include/asm/local.h b/arch/mn10300/include/asm/local.h new file mode 100644 index 0000000..c11c530 --- /dev/null +++ b/arch/mn10300/include/asm/local.h @@ -0,0 +1 @@ +#include <asm-generic/local.h> diff --git a/arch/mn10300/include/asm/mc146818rtc.h b/arch/mn10300/include/asm/mc146818rtc.h new file mode 100644 index 0000000..df6bc6e --- /dev/null +++ b/arch/mn10300/include/asm/mc146818rtc.h @@ -0,0 +1 @@ +#include <asm/rtc-regs.h> diff --git a/arch/mn10300/include/asm/mman.h b/arch/mn10300/include/asm/mman.h new file mode 100644 index 0000000..b7986b6 --- /dev/null +++ b/arch/mn10300/include/asm/mman.h @@ -0,0 +1,28 @@ +/* MN10300 Constants for mmap and co. + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * - Derived from asm-x86/mman.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_MMAN_H +#define _ASM_MMAN_H + +#include <asm-generic/mman.h> + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +#endif /* _ASM_MMAN_H */ diff --git a/arch/mn10300/include/asm/mmu.h b/arch/mn10300/include/asm/mmu.h new file mode 100644 index 0000000..2d2d097 --- /dev/null +++ b/arch/mn10300/include/asm/mmu.h @@ -0,0 +1,19 @@ +/* MN10300 Memory management context + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * - Derived from include/asm-frv/mmu.h + */ + +#ifndef _ASM_MMU_H +#define _ASM_MMU_H + +/* + * MMU context + */ +typedef struct { + unsigned long tlbpid[NR_CPUS]; /* TLB PID for this process on + * each CPU */ +} mm_context_t; + +#endif /* _ASM_MMU_H */ diff --git a/arch/mn10300/include/asm/mmu_context.h b/arch/mn10300/include/asm/mmu_context.h new file mode 100644 index 0000000..a9e2e34 --- /dev/null +++ b/arch/mn10300/include/asm/mmu_context.h @@ -0,0 +1,138 @@ +/* MN10300 MMU context management + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Modified by David Howells (dhowells@redhat.com) + * - Derived from include/asm-m32r/mmu_context.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + * + * + * This implements an algorithm to provide TLB PID mappings to provide + * selective access to the TLB for processes, thus reducing the number of TLB + * flushes required. + * + * Note, however, that the M32R algorithm is technically broken as it does not + * handle version wrap-around, and could, theoretically, have a problem with a + * very long lived program that sleeps long enough for the version number to + * wrap all the way around so that its TLB mappings appear valid once again. + */ +#ifndef _ASM_MMU_CONTEXT_H +#define _ASM_MMU_CONTEXT_H + +#include <asm/atomic.h> +#include <asm/pgalloc.h> +#include <asm/tlbflush.h> +#include <asm-generic/mm_hooks.h> + +#define MMU_CONTEXT_TLBPID_MASK 0x000000ffUL +#define MMU_CONTEXT_VERSION_MASK 0xffffff00UL +#define MMU_CONTEXT_FIRST_VERSION 0x00000100UL +#define MMU_NO_CONTEXT 0x00000000UL + +extern unsigned long mmu_context_cache[NR_CPUS]; +#define mm_context(mm) (mm->context.tlbpid[smp_processor_id()]) + +#define enter_lazy_tlb(mm, tsk) do {} while (0) + +#ifdef CONFIG_SMP +#define cpu_ran_vm(cpu, task) \ + cpu_set((cpu), (task)->cpu_vm_mask) +#define cpu_maybe_ran_vm(cpu, task) \ + cpu_test_and_set((cpu), (task)->cpu_vm_mask) +#else +#define cpu_ran_vm(cpu, task) do {} while (0) +#define cpu_maybe_ran_vm(cpu, task) true +#endif /* CONFIG_SMP */ + +/* + * allocate an MMU context + */ +static inline unsigned long allocate_mmu_context(struct mm_struct *mm) +{ + unsigned long *pmc = &mmu_context_cache[smp_processor_id()]; + unsigned long mc = ++(*pmc); + + if (!(mc & MMU_CONTEXT_TLBPID_MASK)) { + /* we exhausted the TLB PIDs of this version on this CPU, so we + * flush this CPU's TLB in its entirety and start new cycle */ + flush_tlb_all(); + + /* fix the TLB version if needed (we avoid version #0 so as to + * distingush MMU_NO_CONTEXT) */ + if (!mc) + *pmc = mc = MMU_CONTEXT_FIRST_VERSION; + } + mm_context(mm) = mc; + return mc; +} + +/* + * get an MMU context if one is needed + */ +static inline unsigned long get_mmu_context(struct mm_struct *mm) +{ + unsigned long mc = MMU_NO_CONTEXT, cache; + + if (mm) { + cache = mmu_context_cache[smp_processor_id()]; + mc = mm_context(mm); + + /* if we have an old version of the context, replace it */ + if ((mc ^ cache) & MMU_CONTEXT_VERSION_MASK) + mc = allocate_mmu_context(mm); + } + return mc; +} + +/* + * initialise the context related info for a new mm_struct instance + */ +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + int num_cpus = NR_CPUS, i; + + for (i = 0; i < num_cpus; i++) + mm->context.tlbpid[i] = MMU_NO_CONTEXT; + return 0; +} + +/* + * destroy context related info for an mm_struct that is about to be put to + * rest + */ +#define destroy_context(mm) do { } while (0) + +/* + * after we have set current->mm to a new value, this activates the context for + * the new mm so we see the new mappings. + */ +static inline void activate_context(struct mm_struct *mm, int cpu) +{ + PIDR = get_mmu_context(mm) & MMU_CONTEXT_TLBPID_MASK; +} + +/* + * change between virtual memory sets + */ +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + int cpu = smp_processor_id(); + + if (prev != next) { + cpu_ran_vm(cpu, next); + activate_context(next, cpu); + PTBR = (unsigned long) next->pgd; + } else if (!cpu_maybe_ran_vm(cpu, next)) { + activate_context(next, cpu); + } +} + +#define deactivate_mm(tsk, mm) do {} while (0) +#define activate_mm(prev, next) switch_mm((prev), (next), NULL) + +#endif /* _ASM_MMU_CONTEXT_H */ diff --git a/arch/mn10300/include/asm/module.h b/arch/mn10300/include/asm/module.h new file mode 100644 index 0000000..5d7057d --- /dev/null +++ b/arch/mn10300/include/asm/module.h @@ -0,0 +1,27 @@ +/* MN10300 Arch-specific module definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by Mark Salter (msalter@redhat.com) + * Derived from include/asm-i386/module.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_MODULE_H +#define _ASM_MODULE_H + +struct mod_arch_specific { +}; + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr + +/* + * Include the MN10300 architecture version. + */ +#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " " + +#endif /* _ASM_MODULE_H */ diff --git a/arch/mn10300/include/asm/msgbuf.h b/arch/mn10300/include/asm/msgbuf.h new file mode 100644 index 0000000..8b60245 --- /dev/null +++ b/arch/mn10300/include/asm/msgbuf.h @@ -0,0 +1,31 @@ +#ifndef _ASM_MSGBUF_H +#define _ASM_MSGBUF_H + +/* + * The msqid64_ds structure for MN10300 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _ASM_MSGBUF_H */ diff --git a/arch/mn10300/include/asm/mutex.h b/arch/mn10300/include/asm/mutex.h new file mode 100644 index 0000000..84f5490 --- /dev/null +++ b/arch/mn10300/include/asm/mutex.h @@ -0,0 +1,16 @@ +/* MN10300 Mutex fastpath + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + * + * + * TODO: implement optimized primitives instead, or leave the generic + * implementation in place, or pick the atomic_xchg() based generic + * implementation. (see asm-generic/mutex-xchg.h for details) + */ +#include <asm-generic/mutex-null.h> diff --git a/arch/mn10300/include/asm/nmi.h b/arch/mn10300/include/asm/nmi.h new file mode 100644 index 0000000..f3671cb --- /dev/null +++ b/arch/mn10300/include/asm/nmi.h @@ -0,0 +1,14 @@ +/* MN10300 NMI handling + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_NMI_H +#define _ASM_NMI_H + +#endif /* _ASM_NMI_H */ diff --git a/arch/mn10300/include/asm/page.h b/arch/mn10300/include/asm/page.h new file mode 100644 index 0000000..8288e12 --- /dev/null +++ b/arch/mn10300/include/asm/page.h @@ -0,0 +1,128 @@ +/* MN10300 Page table definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PAGE_H +#define _ASM_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 + +#ifndef __ASSEMBLY__ +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE - 1)) +#else +#define PAGE_SIZE +(1 << PAGE_SHIFT) /* unary plus marks an + * immediate val not an addr */ +#define PAGE_MASK +(~(PAGE_SIZE - 1)) +#endif + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +#define copy_page(to, from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) + +#define clear_user_page(addr, vaddr, page) clear_page(addr) +#define copy_user_page(vto, vfrom, vaddr, to) copy_page(vto, vfrom) + +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; + +#define PTE_MASK PAGE_MASK +#define HPAGE_SHIFT 22 + +#ifdef CONFIG_HUGETLB_PAGE +#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) +#define HPAGE_MASK (~(HPAGE_SIZE - 1)) +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) +#endif + +#define pte_val(x) ((x).pte) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) }) +#define __pgd(x) ((pgd_t) { (x) }) +#define __pgprot(x) ((pgprot_t) { (x) }) + +#include <asm-generic/pgtable-nopmd.h> + +#endif /* !__ASSEMBLY__ */ + +/* + * This handles the memory map.. We could make this a config + * option, but too many people screw it up, and too few need + * it. + * + * A __PAGE_OFFSET of 0xC0000000 means that the kernel has + * a virtual address space of one gigabyte, which limits the + * amount of physical memory you can use to about 950MB. + */ + +#ifndef __ASSEMBLY__ + +/* Pure 2^n version of get_order */ +static inline int get_order(unsigned long size) __attribute__((const)); +static inline int get_order(unsigned long size) +{ + int order; + + size = (size - 1) >> (PAGE_SHIFT - 1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +#endif /* __ASSEMBLY__ */ + +#include <asm/page_offset.h> + +#define __PAGE_OFFSET (PAGE_OFFSET_RAW) +#define PAGE_OFFSET ((unsigned long) __PAGE_OFFSET) + +/* + * main RAM and kernel working space are coincident at 0x90000000, but to make + * life more interesting, there's also an uncached virtual shadow at 0xb0000000 + * - these mappings are fixed in the MMU + */ +#define __pfn_disp (CONFIG_KERNEL_RAM_BASE_ADDRESS >> PAGE_SHIFT) + +#define __pa(x) ((unsigned long)(x)) +#define __va(x) ((void *)(unsigned long)(x)) +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +#define pfn_to_page(pfn) (mem_map + ((pfn) - __pfn_disp)) +#define page_to_pfn(page) ((unsigned long)((page) - mem_map) + __pfn_disp) + +#define pfn_valid(pfn) \ +({ \ + unsigned long __pfn = (pfn) - __pfn_disp; \ + __pfn < max_mapnr; \ +}) + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) + +#define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_PAGE_H */ diff --git a/arch/mn10300/include/asm/page_offset.h b/arch/mn10300/include/asm/page_offset.h new file mode 100644 index 0000000..8eb5b16 --- /dev/null +++ b/arch/mn10300/include/asm/page_offset.h @@ -0,0 +1,11 @@ +/* MN10300 Kernel base address + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ +#ifndef _ASM_PAGE_OFFSET_H +#define _ASM_PAGE_OFFSET_H + +#define PAGE_OFFSET_RAW CONFIG_KERNEL_RAM_BASE_ADDRESS + +#endif diff --git a/arch/mn10300/include/asm/param.h b/arch/mn10300/include/asm/param.h new file mode 100644 index 0000000..789b1df --- /dev/null +++ b/arch/mn10300/include/asm/param.h @@ -0,0 +1,34 @@ +/* MN10300 Kernel parameters + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PARAM_H +#define _ASM_PARAM_H + +#ifdef __KERNEL__ +#define HZ CONFIG_HZ /* Internal kernel timer frequency */ +#define USER_HZ 100 /* .. some user interfaces are in + * "ticks" */ +#define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ +#define COMMAND_LINE_SIZE 256 + +#endif /* _ASM_PARAM_H */ diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h new file mode 100644 index 0000000..0517b45 --- /dev/null +++ b/arch/mn10300/include/asm/pci.h @@ -0,0 +1,129 @@ +/* MN10300 PCI definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PCI_H +#define _ASM_PCI_H + +#ifdef __KERNEL__ +#include <linux/mm.h> /* for struct page */ + +#if 0 +#define __pcbdebug(FMT, ADDR, ...) \ + printk(KERN_DEBUG "PCIBRIDGE[%08x]: "FMT"\n", \ + (u32)(ADDR), ##__VA_ARGS__) + +#define __pcidebug(FMT, BUS, DEVFN, WHERE,...) \ +do { \ + printk(KERN_DEBUG "PCI[%02x:%02x.%x + %02x]: "FMT"\n", \ + (BUS)->number, \ + PCI_SLOT(DEVFN), \ + PCI_FUNC(DEVFN), \ + (u32)(WHERE), ##__VA_ARGS__); \ +} while (0) + +#else +#define __pcbdebug(FMT, ADDR, ...) do {} while (0) +#define __pcidebug(FMT, BUS, DEVFN, WHERE, ...) do {} while (0) +#endif + +/* Can be used to override the logic in pci_scan_bus for skipping + * already-configured bus numbers - to be used for buggy BIOSes or + * architectures with incomplete PCI setup by the loader */ + +#ifdef CONFIG_PCI +#define pcibios_assign_all_busses() 1 +extern void unit_pci_init(void); +#else +#define pcibios_assign_all_busses() 0 +#endif + +extern unsigned long pci_mem_start; +#define PCIBIOS_MIN_IO 0xBE000004 +#define PCIBIOS_MIN_MEM 0xB8000000 + +void pcibios_set_master(struct pci_dev *dev); +void pcibios_penalize_isa_irq(int irq); + +/* Dynamic DMA mapping stuff. + * i386 has everything mapped statically. + */ + +#include <linux/types.h> +#include <linux/slab.h> +#include <asm/scatterlist.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <asm/io.h> + +struct pci_dev; + +/* The PCI address space does equal the physical memory + * address space. The networking and block device layers use + * this boolean for bounce buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + + +/* This is always fine. */ +#define pci_dac_dma_supported(pci_dev, mask) (0) + +/* Return the index of the PCI controller for device. */ +static inline int pci_controller_num(struct pci_dev *dev) +{ + return 0; +} + +#define HAVE_PCI_MMAP +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, + int write_combine); + +#endif /* __KERNEL__ */ + +/* implement the pci_ DMA API in terms of the generic device dma_ one */ +#include <asm-generic/pci-dma-compat.h> + +/** + * pcibios_resource_to_bus - convert resource to PCI bus address + * @dev: device which owns this resource + * @region: converted bus-centric region (start,end) + * @res: resource to convert + * + * Convert a resource to a PCI device bus address or bus window. + */ +extern void pcibios_resource_to_bus(struct pci_dev *dev, + struct pci_bus_region *region, + struct resource *res); + +extern void pcibios_bus_to_resource(struct pci_dev *dev, + struct resource *res, + struct pci_bus_region *region); + +static inline struct resource * +pcibios_select_root(struct pci_dev *pdev, struct resource *res) +{ + struct resource *root = NULL; + + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + if (res->flags & IORESOURCE_MEM) + root = &iomem_resource; + + return root; +} + +#define pcibios_scan_all_fns(a, b) 0 + +static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) +{ + return channel ? 15 : 14; +} + +#endif /* _ASM_PCI_H */ diff --git a/arch/mn10300/include/asm/percpu.h b/arch/mn10300/include/asm/percpu.h new file mode 100644 index 0000000..06a959d --- /dev/null +++ b/arch/mn10300/include/asm/percpu.h @@ -0,0 +1 @@ +#include <asm-generic/percpu.h> diff --git a/arch/mn10300/include/asm/pgalloc.h b/arch/mn10300/include/asm/pgalloc.h new file mode 100644 index 0000000..ec057e1 --- /dev/null +++ b/arch/mn10300/include/asm/pgalloc.h @@ -0,0 +1,56 @@ +/* MN10300 Page and page table/directory allocation + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PGALLOC_H +#define _ASM_PGALLOC_H + +#include <asm/processor.h> +#include <asm/page.h> +#include <linux/threads.h> +#include <linux/mm.h> /* for struct page */ + +struct mm_struct; +struct page; + +/* attach a page table to a PMD entry */ +#define pmd_populate_kernel(mm, pmd, pte) \ + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)) + +static inline +void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) +{ + set_pmd(pmd, __pmd((page_to_pfn(pte) << PAGE_SHIFT) | _PAGE_TABLE)); +} +#define pmd_pgtable(pmd) pmd_page(pmd) + +/* + * Allocate and free page tables. + */ + +extern pgd_t *pgd_alloc(struct mm_struct *); +extern void pgd_free(struct mm_struct *, pgd_t *); + +extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); +extern struct page *pte_alloc_one(struct mm_struct *, unsigned long); + +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + free_page((unsigned long) pte); +} + +static inline void pte_free(struct mm_struct *mm, struct page *pte) +{ + __free_page(pte); +} + + +#define __pte_free_tlb(tlb, pte) tlb_remove_page((tlb), (pte)) + +#endif /* _ASM_PGALLOC_H */ diff --git a/arch/mn10300/include/asm/pgtable.h b/arch/mn10300/include/asm/pgtable.h new file mode 100644 index 0000000..6dc30fc --- /dev/null +++ b/arch/mn10300/include/asm/pgtable.h @@ -0,0 +1,492 @@ +/* MN10300 Page table manipulators and constants + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + * + * + * The Linux memory management assumes a three-level page table setup. On + * the i386, we use that, but "fold" the mid level into the top-level page + * table, so that we physically have the same two-level page table as the + * i386 mmu expects. + * + * This file contains the functions and defines necessary to modify and use + * the i386 page table tree for the purposes of the MN10300 TLB handler + * functions. + */ +#ifndef _ASM_PGTABLE_H +#define _ASM_PGTABLE_H + +#include <asm/cpu-regs.h> + +#ifndef __ASSEMBLY__ +#include <asm/processor.h> +#include <asm/cache.h> +#include <linux/threads.h> + +#include <asm/bitops.h> + +#include <linux/slab.h> +#include <linux/list.h> +#include <linux/spinlock.h> + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) +extern unsigned long empty_zero_page[1024]; +extern spinlock_t pgd_lock; +extern struct page *pgd_list; + +extern void pmd_ctor(void *, struct kmem_cache *, unsigned long); +extern void pgtable_cache_init(void); +extern void paging_init(void); + +#endif /* !__ASSEMBLY__ */ + +/* + * The Linux mn10300 paging architecture only implements both the traditional + * 2-level page tables + */ +#define PGDIR_SHIFT 22 +#define PTRS_PER_PGD 1024 +#define PTRS_PER_PUD 1 /* we don't really have any PUD physically */ +#define PTRS_PER_PMD 1 /* we don't really have any PMD physically */ +#define PTRS_PER_PTE 1024 + +#define PGD_SIZE PAGE_SIZE +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE - 1)) + +#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) +#define FIRST_USER_ADDRESS 0 + +#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) +#define KERNEL_PGD_PTRS (PTRS_PER_PGD - USER_PGD_PTRS) + +#define TWOLEVEL_PGDIR_SHIFT 22 +#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT) +#define BOOT_KERNEL_PGD_PTRS (1024 - BOOT_USER_PGD_PTRS) + +#ifndef __ASSEMBLY__ +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +#endif + +/* + * Unfortunately, due to the way the MMU works on the MN10300, the vmalloc VM + * area has to be in the lower half of the virtual address range (the upper + * half is not translated through the TLB). + * + * So in this case, the vmalloc area goes at the bottom of the address map + * (leaving a hole at the very bottom to catch addressing errors), and + * userspace starts immediately above. + * + * The vmalloc() routines also leaves a hole of 4kB between each vmalloced + * area to catch addressing errors. + */ +#define VMALLOC_OFFSET (8 * 1024 * 1024) +#define VMALLOC_START (0x70000000) +#define VMALLOC_END (0x7C000000) + +#ifndef __ASSEMBLY__ +extern pte_t kernel_vmalloc_ptes[(VMALLOC_END - VMALLOC_START) / PAGE_SIZE]; +#endif + +/* IPTEL/DPTEL bit assignments */ +#define _PAGE_BIT_VALID xPTEL_V_BIT +#define _PAGE_BIT_ACCESSED xPTEL_UNUSED1_BIT /* mustn't be loaded into IPTEL/DPTEL */ +#define _PAGE_BIT_NX xPTEL_UNUSED2_BIT /* mustn't be loaded into IPTEL/DPTEL */ +#define _PAGE_BIT_CACHE xPTEL_C_BIT +#define _PAGE_BIT_PRESENT xPTEL_PV_BIT +#define _PAGE_BIT_DIRTY xPTEL_D_BIT +#define _PAGE_BIT_GLOBAL xPTEL_G_BIT + +#define _PAGE_VALID xPTEL_V +#define _PAGE_ACCESSED xPTEL_UNUSED1 +#define _PAGE_NX xPTEL_UNUSED2 /* no-execute bit */ +#define _PAGE_CACHE xPTEL_C +#define _PAGE_PRESENT xPTEL_PV +#define _PAGE_DIRTY xPTEL_D +#define _PAGE_PROT xPTEL_PR +#define _PAGE_PROT_RKNU xPTEL_PR_ROK +#define _PAGE_PROT_WKNU xPTEL_PR_RWK +#define _PAGE_PROT_RKRU xPTEL_PR_ROK_ROU +#define _PAGE_PROT_WKRU xPTEL_PR_RWK_ROU +#define _PAGE_PROT_WKWU xPTEL_PR_RWK_RWU +#define _PAGE_GLOBAL xPTEL_G +#define _PAGE_PSE xPTEL_PS_4Mb /* 4MB page */ + +#define _PAGE_FILE xPTEL_UNUSED1_BIT /* set:pagecache unset:swap */ + +#define __PAGE_PROT_UWAUX 0x040 +#define __PAGE_PROT_USER 0x080 +#define __PAGE_PROT_WRITE 0x100 + +#define _PAGE_PRESENTV (_PAGE_PRESENT|_PAGE_VALID) +#define _PAGE_PROTNONE 0x000 /* If not present */ + +#ifndef __ASSEMBLY__ + +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) + +#define _PAGE_TABLE (_PAGE_PRESENTV | _PAGE_PROT_WKNU | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define __PAGE_NONE (_PAGE_PRESENTV | _PAGE_PROT_RKNU | _PAGE_ACCESSED | _PAGE_CACHE) +#define __PAGE_SHARED (_PAGE_PRESENTV | _PAGE_PROT_WKWU | _PAGE_ACCESSED | _PAGE_CACHE) +#define __PAGE_COPY (_PAGE_PRESENTV | _PAGE_PROT_RKRU | _PAGE_ACCESSED | _PAGE_CACHE) +#define __PAGE_READONLY (_PAGE_PRESENTV | _PAGE_PROT_RKRU | _PAGE_ACCESSED | _PAGE_CACHE) + +#define PAGE_NONE __pgprot(__PAGE_NONE | _PAGE_NX) +#define PAGE_SHARED_NOEXEC __pgprot(__PAGE_SHARED | _PAGE_NX) +#define PAGE_COPY_NOEXEC __pgprot(__PAGE_COPY | _PAGE_NX) +#define PAGE_READONLY_NOEXEC __pgprot(__PAGE_READONLY | _PAGE_NX) +#define PAGE_SHARED_EXEC __pgprot(__PAGE_SHARED) +#define PAGE_COPY_EXEC __pgprot(__PAGE_COPY) +#define PAGE_READONLY_EXEC __pgprot(__PAGE_READONLY) +#define PAGE_COPY PAGE_COPY_NOEXEC +#define PAGE_READONLY PAGE_READONLY_NOEXEC +#define PAGE_SHARED PAGE_SHARED_EXEC + +#define __PAGE_KERNEL_BASE (_PAGE_PRESENTV | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL) + +#define __PAGE_KERNEL (__PAGE_KERNEL_BASE | _PAGE_PROT_WKNU | _PAGE_CACHE | _PAGE_NX) +#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL_BASE | _PAGE_PROT_WKNU | _PAGE_NX) +#define __PAGE_KERNEL_EXEC (__PAGE_KERNEL & ~_PAGE_NX) +#define __PAGE_KERNEL_RO (__PAGE_KERNEL_BASE | _PAGE_PROT_RKNU | _PAGE_CACHE | _PAGE_NX) +#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) +#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) + +#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) +#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) +#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) +#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) + +/* + * Whilst the MN10300 can do page protection for execute (given separate data + * and insn TLBs), we are not supporting it at the moment. Write permission, + * however, always implies read permission (but not execute permission). + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY_NOEXEC +#define __P010 PAGE_COPY_NOEXEC +#define __P011 PAGE_COPY_NOEXEC +#define __P100 PAGE_READONLY_EXEC +#define __P101 PAGE_READONLY_EXEC +#define __P110 PAGE_COPY_EXEC +#define __P111 PAGE_COPY_EXEC + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY_NOEXEC +#define __S010 PAGE_SHARED_NOEXEC +#define __S011 PAGE_SHARED_NOEXEC +#define __S100 PAGE_READONLY_EXEC +#define __S101 PAGE_READONLY_EXEC +#define __S110 PAGE_SHARED_EXEC +#define __S111 PAGE_SHARED_EXEC + +/* + * Define this to warn about kernel memory accesses that are + * done without a 'verify_area(VERIFY_WRITE,..)' + */ +#undef TEST_VERIFY_AREA + +#define pte_present(x) (pte_val(x) & _PAGE_VALID) +#define pte_clear(mm, addr, xp) \ +do { \ + set_pte_at((mm), (addr), (xp), __pte(0)); \ +} while (0) + +#define pmd_none(x) (!pmd_val(x)) +#define pmd_present(x) (!pmd_none(x)) +#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad(x) 0 + + +#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) + +#ifndef __ASSEMBLY__ + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_user(pte_t pte) { return pte_val(pte) & __PAGE_PROT_USER; } +static inline int pte_read(pte_t pte) { return pte_val(pte) & __PAGE_PROT_USER; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & __PAGE_PROT_WRITE; } +static inline int pte_special(pte_t pte){ return 0; } + +/* + * The following only works if pte_present() is not true. + */ +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } + +static inline pte_t pte_rdprotect(pte_t pte) +{ + pte_val(pte) &= ~(__PAGE_PROT_USER|__PAGE_PROT_UWAUX); return pte; +} +static inline pte_t pte_exprotect(pte_t pte) +{ + pte_val(pte) |= _PAGE_NX; return pte; +} + +static inline pte_t pte_wrprotect(pte_t pte) +{ + pte_val(pte) &= ~(__PAGE_PROT_WRITE|__PAGE_PROT_UWAUX); return pte; +} + +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= ~_PAGE_NX; return pte; } + +static inline pte_t pte_mkread(pte_t pte) +{ + pte_val(pte) |= __PAGE_PROT_USER; + if (pte_write(pte)) + pte_val(pte) |= __PAGE_PROT_UWAUX; + return pte; +} +static inline pte_t pte_mkwrite(pte_t pte) +{ + pte_val(pte) |= __PAGE_PROT_WRITE; + if (pte_val(pte) & __PAGE_PROT_USER) + pte_val(pte) |= __PAGE_PROT_UWAUX; + return pte; +} + +static inline pte_t pte_mkspecial(pte_t pte) { return pte; } + +#define pte_ERROR(e) \ + printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \ + __FILE__, __LINE__, pte_val(e)) +#define pgd_ERROR(e) \ + printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \ + __FILE__, __LINE__, pgd_val(e)) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +#define pgd_clear(xp) do { } while (0) + +/* + * Certain architectures need to do special things when PTEs + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) (*(pteptr) = pteval) +#define set_pte_at(mm, addr, ptep, pteval) set_pte((ptep), (pteval)) +#define set_pte_atomic(pteptr, pteval) set_pte((pteptr), (pteval)) + +/* + * (pmds are folded into pgds so this doesn't get actually called, + * but the define is needed for a generic inline function.) + */ +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) + +#define ptep_get_and_clear(mm, addr, ptep) \ + __pte(xchg(&(ptep)->pte, 0)) +#define pte_same(a, b) (pte_val(a) == pte_val(b)) +#define pte_page(x) pfn_to_page(pte_pfn(x)) +#define pte_none(x) (!pte_val(x)) +#define pte_pfn(x) ((unsigned long) (pte_val(x) >> PAGE_SHIFT)) +#define __pfn_addr(pfn) ((pfn) << PAGE_SHIFT) +#define pfn_pte(pfn, prot) __pte(__pfn_addr(pfn) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) __pmd(__pfn_addr(pfn) | pgprot_val(prot)) + +/* + * All present user pages are user-executable: + */ +static inline int pte_exec(pte_t pte) +{ + return pte_user(pte); +} + +/* + * All present pages are kernel-executable: + */ +static inline int pte_exec_kernel(pte_t pte) +{ + return 1; +} + +/* + * Bits 0 and 1 are taken, split up the 29 bits of offset + * into this range: + */ +#define PTE_FILE_MAX_BITS 29 + +#define pte_to_pgoff(pte) (pte_val(pte) >> 2) +#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE) + +/* Encode and de-code a swap entry */ +#define __swp_type(x) (((x).val >> 2) & 0x3f) +#define __swp_offset(x) ((x).val >> 8) +#define __swp_entry(type, offset) \ + ((swp_entry_t) { ((type) << 2) | ((offset) << 8) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) __pte((x).val) + +static inline +int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, + pte_t *ptep) +{ + if (!pte_dirty(*ptep)) + return 0; + return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte); +} + +static inline +int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, + pte_t *ptep) +{ + if (!pte_young(*ptep)) + return 0; + return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte); +} + +static inline +void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + pte_val(*ptep) &= ~(__PAGE_PROT_WRITE|__PAGE_PROT_UWAUX); +} + +static inline void ptep_mkdirty(pte_t *ptep) +{ + set_bit(_PAGE_BIT_DIRTY, &ptep->pte); +} + +/* + * Macro to mark a page protection value as "uncacheable". On processors which + * do not support it, this is a no-op. + */ +#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_CACHE) + + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ + +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) +#define mk_pte_huge(entry) \ + ((entry).pte |= _PAGE_PRESENT | _PAGE_PSE | _PAGE_VALID) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) &= _PAGE_CHG_MASK; + pte_val(pte) |= pgprot_val(newprot); + return pte; +} + +#define page_pte(page) page_pte_prot((page), __pgprot(0)) + +#define pmd_page_kernel(pmd) \ + ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) + +#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) + +#define pmd_large(pmd) \ + ((pmd_val(pmd) & (_PAGE_PSE | _PAGE_PRESENT)) == \ + (_PAGE_PSE | _PAGE_PRESENT)) + +/* + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD] + * + * this macro returns the index of the entry in the pgd page which would + * control the given virtual address + */ +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) + +/* + * pgd_offset() returns a (pgd_t *) + * pgd_index() is used get the offset into the pgd page's array of pgd_t's; + */ +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) + +/* + * a shortcut which implies the use of the kernel's pgd, instead + * of a process's + */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* + * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD] + * + * this macro returns the index of the entry in the pmd page which would + * control the given virtual address + */ +#define pmd_index(address) \ + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) + +/* + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE] + * + * this macro returns the index of the entry in the pte page which would + * control the given virtual address + */ +#define pte_index(address) \ + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address)) + +/* + * Make a given kernel text page executable/non-executable. + * Returns the previous executability setting of that page (which + * is used to restore the previous state). Used by the SMP bootup code. + * NOTE: this is an __init function for security reasons. + */ +static inline int set_kernel_exec(unsigned long vaddr, int enable) +{ + return 0; +} + +#define pte_offset_map(dir, address) \ + ((pte_t *) page_address(pmd_page(*(dir))) + pte_index(address)) +#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address) +#define pte_unmap(pte) do {} while (0) +#define pte_unmap_nested(pte) do {} while (0) + +/* + * The MN10300 has external MMU info in the form of a TLB: this is adapted from + * the kernel page tables containing the necessary information by tlb-mn10300.S + */ +extern void update_mmu_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte); + +#endif /* !__ASSEMBLY__ */ + +#define kern_addr_valid(addr) (1) + +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range((vma), (vaddr), (pfn), (size), (prot)) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG +#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +#define __HAVE_ARCH_PTEP_SET_WRPROTECT +#define __HAVE_ARCH_PTEP_MKDIRTY +#define __HAVE_ARCH_PTE_SAME +#include <asm-generic/pgtable.h> + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_PGTABLE_H */ diff --git a/arch/mn10300/include/asm/pio-regs.h b/arch/mn10300/include/asm/pio-regs.h new file mode 100644 index 0000000..96bc818 --- /dev/null +++ b/arch/mn10300/include/asm/pio-regs.h @@ -0,0 +1,233 @@ +/* MN10300 On-board I/O port module registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PIO_REGS_H +#define _ASM_PIO_REGS_H + +#include <asm/cpu-regs.h> +#include <asm/intctl-regs.h> + +#ifdef __KERNEL__ + +/* I/O port 0 */ +#define P0MD __SYSREG(0xdb000000, u16) /* mode reg */ +#define P0MD_0 0x0003 /* mask */ +#define P0MD_0_IN 0x0000 /* input mode */ +#define P0MD_0_OUT 0x0001 /* output mode */ +#define P0MD_0_TM0IO 0x0002 /* timer 0 I/O mode */ +#define P0MD_0_EYECLK 0x0003 /* test signal output (clock) */ +#define P0MD_1 0x000c +#define P0MD_1_IN 0x0000 +#define P0MD_1_OUT 0x0004 +#define P0MD_1_TM1IO 0x0008 /* timer 1 I/O mode */ +#define P0MD_1_EYED 0x000c /* test signal output (data) */ +#define P0MD_2 0x0030 +#define P0MD_2_IN 0x0000 +#define P0MD_2_OUT 0x0010 +#define P0MD_2_TM2IO 0x0020 /* timer 2 I/O mode */ +#define P0MD_3 0x00c0 +#define P0MD_3_IN 0x0000 +#define P0MD_3_OUT 0x0040 +#define P0MD_3_TM3IO 0x0080 /* timer 3 I/O mode */ +#define P0MD_4 0x0300 +#define P0MD_4_IN 0x0000 +#define P0MD_4_OUT 0x0100 +#define P0MD_4_TM4IO 0x0200 /* timer 4 I/O mode */ +#define P0MD_4_XCTS 0x0300 /* XCTS input for serial port 2 */ +#define P0MD_5 0x0c00 +#define P0MD_5_IN 0x0000 +#define P0MD_5_OUT 0x0400 +#define P0MD_5_TM5IO 0x0800 /* timer 5 I/O mode */ +#define P0MD_6 0x3000 +#define P0MD_6_IN 0x0000 +#define P0MD_6_OUT 0x1000 +#define P0MD_6_TM6IOA 0x2000 /* timer 6 I/O mode A */ +#define P0MD_7 0xc000 +#define P0MD_7_IN 0x0000 +#define P0MD_7_OUT 0x4000 +#define P0MD_7_TM6IOB 0x8000 /* timer 6 I/O mode B */ + +#define P0IN __SYSREG(0xdb000004, u8) /* in reg */ +#define P0OUT __SYSREG(0xdb000008, u8) /* out reg */ + +#define P0TMIO __SYSREG(0xdb00000c, u8) /* TM pin I/O control reg */ +#define P0TMIO_TM0_IN 0x00 +#define P0TMIO_TM0_OUT 0x01 +#define P0TMIO_TM1_IN 0x00 +#define P0TMIO_TM1_OUT 0x02 +#define P0TMIO_TM2_IN 0x00 +#define P0TMIO_TM2_OUT 0x04 +#define P0TMIO_TM3_IN 0x00 +#define P0TMIO_TM3_OUT 0x08 +#define P0TMIO_TM4_IN 0x00 +#define P0TMIO_TM4_OUT 0x10 +#define P0TMIO_TM5_IN 0x00 +#define P0TMIO_TM5_OUT 0x20 +#define P0TMIO_TM6A_IN 0x00 +#define P0TMIO_TM6A_OUT 0x40 +#define P0TMIO_TM6B_IN 0x00 +#define P0TMIO_TM6B_OUT 0x80 + +/* I/O port 1 */ +#define P1MD __SYSREG(0xdb000100, u16) /* mode reg */ +#define P1MD_0 0x0003 /* mask */ +#define P1MD_0_IN 0x0000 /* input mode */ +#define P1MD_0_OUT 0x0001 /* output mode */ +#define P1MD_0_TM7IO 0x0002 /* timer 7 I/O mode */ +#define P1MD_0_ADTRG 0x0003 /* A/D converter trigger mode */ +#define P1MD_1 0x000c +#define P1MD_1_IN 0x0000 +#define P1MD_1_OUT 0x0004 +#define P1MD_1_TM8IO 0x0008 /* timer 8 I/O mode */ +#define P1MD_1_XDMR0 0x000c /* DMA request input 0 mode */ +#define P1MD_2 0x0030 +#define P1MD_2_IN 0x0000 +#define P1MD_2_OUT 0x0010 +#define P1MD_2_TM9IO 0x0020 /* timer 9 I/O mode */ +#define P1MD_2_XDMR1 0x0030 /* DMA request input 1 mode */ +#define P1MD_3 0x00c0 +#define P1MD_3_IN 0x0000 +#define P1MD_3_OUT 0x0040 +#define P1MD_3_TM10IO 0x0080 /* timer 10 I/O mode */ +#define P1MD_3_FRQS0 0x00c0 /* CPU clock multiplier setting input 0 mode */ +#define P1MD_4 0x0300 +#define P1MD_4_IN 0x0000 +#define P1MD_4_OUT 0x0100 +#define P1MD_4_TM11IO 0x0200 /* timer 11 I/O mode */ +#define P1MD_4_FRQS1 0x0300 /* CPU clock multiplier setting input 1 mode */ + +#define P1IN __SYSREG(0xdb000104, u8) /* in reg */ +#define P1OUT __SYSREG(0xdb000108, u8) /* out reg */ +#define P1TMIO __SYSREG(0xdb00010c, u8) /* TM pin I/O control reg */ +#define P1TMIO_TM11_IN 0x00 +#define P1TMIO_TM11_OUT 0x01 +#define P1TMIO_TM10_IN 0x00 +#define P1TMIO_TM10_OUT 0x02 +#define P1TMIO_TM9_IN 0x00 +#define P1TMIO_TM9_OUT 0x04 +#define P1TMIO_TM8_IN 0x00 +#define P1TMIO_TM8_OUT 0x08 +#define P1TMIO_TM7_IN 0x00 +#define P1TMIO_TM7_OUT 0x10 + +/* I/O port 2 */ +#define P2MD __SYSREG(0xdb000200, u16) /* mode reg */ +#define P2MD_0 0x0003 /* mask */ +#define P2MD_0_IN 0x0000 /* input mode */ +#define P2MD_0_OUT 0x0001 /* output mode */ +#define P2MD_0_BOOTBW 0x0003 /* boot bus width selector mode */ +#define P2MD_1 0x000c +#define P2MD_1_IN 0x0000 +#define P2MD_1_OUT 0x0004 +#define P2MD_1_BOOTSEL 0x000c /* boot device selector mode */ +#define P2MD_2 0x0030 +#define P2MD_2_IN 0x0000 +#define P2MD_2_OUT 0x0010 +#define P2MD_3 0x00c0 +#define P2MD_3_IN 0x0000 +#define P2MD_3_OUT 0x0040 +#define P2MD_3_CKIO 0x00c0 /* mode */ +#define P2MD_4 0x0300 +#define P2MD_4_IN 0x0000 +#define P2MD_4_OUT 0x0100 +#define P2MD_4_CMOD 0x0300 /* mode */ + +#define P2IN __SYSREG(0xdb000204, u8) /* in reg */ +#define P2OUT __SYSREG(0xdb000208, u8) /* out reg */ +#define P2TMIO __SYSREG(0xdb00020c, u8) /* TM pin I/O control reg */ + +/* I/O port 3 */ +#define P3MD __SYSREG(0xdb000300, u16) /* mode reg */ +#define P3MD_0 0x0003 /* mask */ +#define P3MD_0_IN 0x0000 /* input mode */ +#define P3MD_0_OUT 0x0001 /* output mode */ +#define P3MD_0_AFRXD 0x0002 /* AFR interface mode */ +#define P3MD_1 0x000c +#define P3MD_1_IN 0x0000 +#define P3MD_1_OUT 0x0004 +#define P3MD_1_AFTXD 0x0008 /* AFR interface mode */ +#define P3MD_2 0x0030 +#define P3MD_2_IN 0x0000 +#define P3MD_2_OUT 0x0010 +#define P3MD_2_AFSCLK 0x0020 /* AFR interface mode */ +#define P3MD_3 0x00c0 +#define P3MD_3_IN 0x0000 +#define P3MD_3_OUT 0x0040 +#define P3MD_3_AFFS 0x0080 /* AFR interface mode */ +#define P3MD_4 0x0300 +#define P3MD_4_IN 0x0000 +#define P3MD_4_OUT 0x0100 +#define P3MD_4_AFEHC 0x0200 /* AFR interface mode */ + +#define P3IN __SYSREG(0xdb000304, u8) /* in reg */ +#define P3OUT __SYSREG(0xdb000308, u8) /* out reg */ + +/* I/O port 4 */ +#define P4MD __SYSREG(0xdb000400, u16) /* mode reg */ +#define P4MD_0 0x0003 /* mask */ +#define P4MD_0_IN 0x0000 /* input mode */ +#define P4MD_0_OUT 0x0001 /* output mode */ +#define P4MD_0_SCL0 0x0002 /* I2C/serial mode */ +#define P4MD_1 0x000c +#define P4MD_1_IN 0x0000 +#define P4MD_1_OUT 0x0004 +#define P4MD_1_SDA0 0x0008 +#define P4MD_2 0x0030 +#define P4MD_2_IN 0x0000 +#define P4MD_2_OUT 0x0010 +#define P4MD_2_SCL1 0x0020 +#define P4MD_3 0x00c0 +#define P4MD_3_IN 0x0000 +#define P4MD_3_OUT 0x0040 +#define P4MD_3_SDA1 0x0080 +#define P4MD_4 0x0300 +#define P4MD_4_IN 0x0000 +#define P4MD_4_OUT 0x0100 +#define P4MD_4_SBO0 0x0200 +#define P4MD_5 0x0c00 +#define P4MD_5_IN 0x0000 +#define P4MD_5_OUT 0x0400 +#define P4MD_5_SBO1 0x0800 +#define P4MD_6 0x3000 +#define P4MD_6_IN 0x0000 +#define P4MD_6_OUT 0x1000 +#define P4MD_6_SBT0 0x2000 +#define P4MD_7 0xc000 +#define P4MD_7_IN 0x0000 +#define P4MD_7_OUT 0x4000 +#define P4MD_7_SBT1 0x8000 + +#define P4IN __SYSREG(0xdb000404, u8) /* in reg */ +#define P4OUT __SYSREG(0xdb000408, u8) /* out reg */ + +/* I/O port 5 */ +#define P5MD __SYSREG(0xdb000500, u16) /* mode reg */ +#define P5MD_0 0x0003 /* mask */ +#define P5MD_0_IN 0x0000 /* input mode */ +#define P5MD_0_OUT 0x0001 /* output mode */ +#define P5MD_0_IRTXD 0x0002 /* IrDA mode */ +#define P5MD_0_SOUT 0x0004 /* serial mode */ +#define P5MD_1 0x000c +#define P5MD_1_IN 0x0000 +#define P5MD_1_OUT 0x0004 +#define P5MD_1_IRRXDS 0x0008 /* IrDA mode */ +#define P5MD_1_SIN 0x000c /* serial mode */ +#define P5MD_2 0x0030 +#define P5MD_2_IN 0x0000 +#define P5MD_2_OUT 0x0010 +#define P5MD_2_IRRXDF 0x0020 /* IrDA mode */ + +#define P5IN __SYSREG(0xdb000504, u8) /* in reg */ +#define P5OUT __SYSREG(0xdb000508, u8) /* out reg */ + + +#endif /* __KERNEL__ */ + +#endif /* _ASM_PIO_REGS_H */ diff --git a/arch/mn10300/include/asm/poll.h b/arch/mn10300/include/asm/poll.h new file mode 100644 index 0000000..c98509d --- /dev/null +++ b/arch/mn10300/include/asm/poll.h @@ -0,0 +1 @@ +#include <asm-generic/poll.h> diff --git a/arch/mn10300/include/asm/posix_types.h b/arch/mn10300/include/asm/posix_types.h new file mode 100644 index 0000000..077567c --- /dev/null +++ b/arch/mn10300/include/asm/posix_types.h @@ -0,0 +1,132 @@ +/* MN10300 POSIX types + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_POSIX_TYPES_H +#define _ASM_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +static inline void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + __fdsetp->fds_bits[__tmp] |= (1UL<<__rem); +} + +#undef __FD_CLR +static inline void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem); +} + + +#undef __FD_ISSET +static inline int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p) +{ + unsigned long __tmp = __fd / __NFDBITS; + unsigned long __rem = __fd % __NFDBITS; + return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static inline void __FD_ZERO(__kernel_fd_set *__p) +{ + unsigned long *__tmp = __p->fds_bits; + int __i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 16: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + __tmp[ 4] = 0; __tmp[ 5] = 0; + __tmp[ 6] = 0; __tmp[ 7] = 0; + __tmp[ 8] = 0; __tmp[ 9] = 0; + __tmp[10] = 0; __tmp[11] = 0; + __tmp[12] = 0; __tmp[13] = 0; + __tmp[14] = 0; __tmp[15] = 0; + return; + + case 8: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + __tmp[ 4] = 0; __tmp[ 5] = 0; + __tmp[ 6] = 0; __tmp[ 7] = 0; + return; + + case 4: + __tmp[ 0] = 0; __tmp[ 1] = 0; + __tmp[ 2] = 0; __tmp[ 3] = 0; + return; + } + } + __i = __FDSET_LONGS; + while (__i) { + __i--; + *__tmp = 0; + __tmp++; + } +} + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif /* _ASM_POSIX_TYPES_H */ diff --git a/arch/mn10300/include/asm/processor.h b/arch/mn10300/include/asm/processor.h new file mode 100644 index 0000000..7323927 --- /dev/null +++ b/arch/mn10300/include/asm/processor.h @@ -0,0 +1,186 @@ +/* MN10300 Processor specifics + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_PROCESSOR_H +#define _ASM_PROCESSOR_H + +#include <asm/page.h> +#include <asm/ptrace.h> +#include <asm/cpu-regs.h> +#include <linux/threads.h> + +/* Forward declaration, a strange C thing */ +struct task_struct; +struct mm_struct; + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() \ +({ \ + void *__pc; \ + asm("mov pc,%0" : "=a"(__pc)); \ + __pc; \ +}) + +extern void show_registers(struct pt_regs *regs); + +/* + * CPU type and hardware bug flags. Kept separately for each CPU. + * Members of this structure are referenced in head.S, so think twice + * before touching them. [mj] + */ + +struct mn10300_cpuinfo { + int type; + unsigned long loops_per_sec; + char hard_math; + unsigned long *pgd_quick; + unsigned long *pte_quick; + unsigned long pgtable_cache_sz; +}; + +extern struct mn10300_cpuinfo boot_cpu_data; + +#define cpu_data &boot_cpu_data +#define current_cpu_data boot_cpu_data + +extern void identify_cpu(struct mn10300_cpuinfo *); +extern void print_cpu_info(struct mn10300_cpuinfo *); +extern void dodgy_tsc(void); +#define cpu_relax() barrier() + +/* + * User space process size: 1.75GB (default). + */ +#define TASK_SIZE 0x70000000 + +/* + * Where to put the userspace stack by default + */ +#define STACK_TOP 0x70000000 +#define STACK_TOP_MAX STACK_TOP + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE 0x30000000 + +typedef struct { + unsigned long seg; +} mm_segment_t; + +struct fpu_state_struct { + unsigned long fs[32]; /* fpu registers */ + unsigned long fpcr; /* fpu control register */ +}; + +struct thread_struct { + struct pt_regs *uregs; /* userspace register frame */ + unsigned long pc; /* kernel PC */ + unsigned long sp; /* kernel SP */ + unsigned long a3; /* kernel FP */ + unsigned long wchan; + unsigned long usp; + struct pt_regs *__frame; + unsigned long fpu_flags; +#define THREAD_USING_FPU 0x00000001 /* T if this task is using the FPU */ + struct fpu_state_struct fpu_state; +}; + +#define INIT_THREAD \ +{ \ + .uregs = init_uregs, \ + .pc = 0, \ + .sp = 0, \ + .a3 = 0, \ + .wchan = 0, \ + .__frame = NULL, \ +} + +#define INIT_MMAP \ +{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \ + NULL, NULL } + +/* + * do necessary setup to start up a newly executed thread + * - need to discard the frame stacked by the kernel thread invoking the execve + * syscall (see RESTORE_ALL macro) + */ +#define start_thread(regs, new_pc, new_sp) do { \ + set_fs(USER_DS); \ + __frame = current->thread.uregs; \ + __frame->epsw = EPSW_nSL | EPSW_IE | EPSW_IM; \ + __frame->pc = new_pc; \ + __frame->sp = new_sp; \ +} while (0) + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); + +/* Prepare to copy thread state - unlazy all lazy status */ +extern void prepare_to_copy(struct task_struct *tsk); + +/* + * create a kernel thread without removing it from tasklists + */ +extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); + +/* + * Return saved PC of a blocked thread. + */ +extern unsigned long thread_saved_pc(struct task_struct *tsk); + +unsigned long get_wchan(struct task_struct *p); + +#define task_pt_regs(task) \ +({ \ + struct pt_regs *__regs__; \ + __regs__ = (struct pt_regs *) (KSTK_TOP(task_stack_page(task)) - 8); \ + __regs__ - 1; \ +}) + +#define KSTK_EIP(task) (task_pt_regs(task)->pc) +#define KSTK_ESP(task) (task_pt_regs(task)->sp) + +#define KSTK_TOP(info) \ +({ \ + (unsigned long)(info) + THREAD_SIZE; \ +}) + +#define ARCH_HAS_PREFETCH +#define ARCH_HAS_PREFETCHW + +static inline void prefetch(const void *x) +{ +#ifndef CONFIG_MN10300_CACHE_DISABLED +#ifdef CONFIG_MN10300_PROC_MN103E010 + asm volatile ("nop; nop; dcpf (%0)" : : "r"(x)); +#else + asm volatile ("dcpf (%0)" : : "r"(x)); +#endif +#endif +} + +static inline void prefetchw(const void *x) +{ +#ifndef CONFIG_MN10300_CACHE_DISABLED +#ifdef CONFIG_MN10300_PROC_MN103E010 + asm volatile ("nop; nop; dcpf (%0)" : : "r"(x)); +#else + asm volatile ("dcpf (%0)" : : "r"(x)); +#endif +#endif +} + +#endif /* _ASM_PROCESSOR_H */ diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h new file mode 100644 index 0000000..7b06cc6 --- /dev/null +++ b/arch/mn10300/include/asm/ptrace.h @@ -0,0 +1,103 @@ +/* MN10300 Exception frame layout and ptrace constants + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PTRACE_H +#define _ASM_PTRACE_H + +#define PT_A3 0 +#define PT_A2 1 +#define PT_D3 2 +#define PT_D2 3 +#define PT_MCVF 4 +#define PT_MCRL 5 +#define PT_MCRH 6 +#define PT_MDRQ 7 +#define PT_E1 8 +#define PT_E0 9 +#define PT_E7 10 +#define PT_E6 11 +#define PT_E5 12 +#define PT_E4 13 +#define PT_E3 14 +#define PT_E2 15 +#define PT_SP 16 +#define PT_LAR 17 +#define PT_LIR 18 +#define PT_MDR 19 +#define PT_A1 20 +#define PT_A0 21 +#define PT_D1 22 +#define PT_D0 23 +#define PT_ORIG_D0 24 +#define PT_EPSW 25 +#define PT_PC 26 +#define NR_PTREGS 27 + +#ifndef __ASSEMBLY__ +/* + * This defines the way registers are stored in the event of an exception + * - the strange order is due to the MOVM instruction + */ +struct pt_regs { + unsigned long a3; /* syscall arg 3 */ + unsigned long a2; /* syscall arg 4 */ + unsigned long d3; /* syscall arg 5 */ + unsigned long d2; /* syscall arg 6 */ + unsigned long mcvf; + unsigned long mcrl; + unsigned long mcrh; + unsigned long mdrq; + unsigned long e1; + unsigned long e0; + unsigned long e7; + unsigned long e6; + unsigned long e5; + unsigned long e4; + unsigned long e3; + unsigned long e2; + unsigned long sp; + unsigned long lar; + unsigned long lir; + unsigned long mdr; + unsigned long a1; + unsigned long a0; /* syscall arg 1 */ + unsigned long d1; /* syscall arg 2 */ + unsigned long d0; /* syscall ret */ + struct pt_regs *next; /* next frame pointer */ + unsigned long orig_d0; /* syscall number */ + unsigned long epsw; + unsigned long pc; +}; +#endif + +extern struct pt_regs *__frame; /* current frame pointer */ + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + +#if defined(__KERNEL__) + +#if !defined(__ASSEMBLY__) +#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) +#define instruction_pointer(regs) ((regs)->pc) +extern void show_regs(struct pt_regs *); +#endif /* !__ASSEMBLY */ + +#define profile_pc(regs) ((regs)->pc) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_PTRACE_H */ diff --git a/arch/mn10300/include/asm/reset-regs.h b/arch/mn10300/include/asm/reset-regs.h new file mode 100644 index 0000000..174523d --- /dev/null +++ b/arch/mn10300/include/asm/reset-regs.h @@ -0,0 +1,64 @@ +/* MN10300 Reset controller and watchdog timer definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_RESET_REGS_H +#define _ASM_RESET_REGS_H + +#include <asm/cpu-regs.h> +#include <asm/exceptions.h> + +#ifdef __KERNEL__ + +#ifdef CONFIG_MN10300_WD_TIMER +#define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ +#endif + +/* + * watchdog timer registers + */ +#define WDBC __SYSREGC(0xc0001000, u8) /* watchdog binary counter reg */ + +#define WDCTR __SYSREG(0xc0001002, u8) /* watchdog timer control reg */ +#define WDCTR_WDCK 0x07 /* clock source selection */ +#define WDCTR_WDCK_256th 0x00 /* - OSCI/256 */ +#define WDCTR_WDCK_1024th 0x01 /* - OSCI/1024 */ +#define WDCTR_WDCK_2048th 0x02 /* - OSCI/2048 */ +#define WDCTR_WDCK_16384th 0x03 /* - OSCI/16384 */ +#define WDCTR_WDCK_65536th 0x04 /* - OSCI/65536 */ +#define WDCTR_WDRST 0x40 /* binary counter reset */ +#define WDCTR_WDCNE 0x80 /* watchdog timer enable */ + +#define RSTCTR __SYSREG(0xc0001004, u8) /* reset control reg */ +#define RSTCTR_CHIPRST 0x01 /* chip reset */ +#define RSTCTR_DBFRST 0x02 /* double fault reset flag */ +#define RSTCTR_WDTRST 0x04 /* watchdog timer reset flag */ +#define RSTCTR_WDREN 0x08 /* watchdog timer reset enable */ + +#ifndef __ASSEMBLY__ + +static inline void mn10300_proc_hard_reset(void) +{ + RSTCTR &= ~RSTCTR_CHIPRST; + RSTCTR |= RSTCTR_CHIPRST; +} + +extern unsigned int watchdog_alert_counter; + +extern void watchdog_go(void); +extern asmlinkage void watchdog_handler(void); +extern asmlinkage +void watchdog_interrupt(struct pt_regs *, enum exception_code); + +#endif + +#endif /* __KERNEL__ */ + +#endif /* _ASM_RESET_REGS_H */ diff --git a/arch/mn10300/include/asm/resource.h b/arch/mn10300/include/asm/resource.h new file mode 100644 index 0000000..04bc4db --- /dev/null +++ b/arch/mn10300/include/asm/resource.h @@ -0,0 +1 @@ +#include <asm-generic/resource.h> diff --git a/arch/mn10300/include/asm/rtc-regs.h b/arch/mn10300/include/asm/rtc-regs.h new file mode 100644 index 0000000..c42deef --- /dev/null +++ b/arch/mn10300/include/asm/rtc-regs.h @@ -0,0 +1,86 @@ +/* MN10300 on-chip Real-Time Clock registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_RTC_REGS_H +#define _ASM_RTC_REGS_H + +#include <asm/intctl-regs.h> + +#ifdef __KERNEL__ + +#define RTSCR __SYSREG(0xd8600000, u8) /* RTC seconds count reg */ +#define RTSAR __SYSREG(0xd8600001, u8) /* RTC seconds alarm reg */ +#define RTMCR __SYSREG(0xd8600002, u8) /* RTC minutes count reg */ +#define RTMAR __SYSREG(0xd8600003, u8) /* RTC minutes alarm reg */ +#define RTHCR __SYSREG(0xd8600004, u8) /* RTC hours count reg */ +#define RTHAR __SYSREG(0xd8600005, u8) /* RTC hours alarm reg */ +#define RTDWCR __SYSREG(0xd8600006, u8) /* RTC day of the week count reg */ +#define RTDMCR __SYSREG(0xd8600007, u8) /* RTC days count reg */ +#define RTMTCR __SYSREG(0xd8600008, u8) /* RTC months count reg */ +#define RTYCR __SYSREG(0xd8600009, u8) /* RTC years count reg */ + +#define RTCRA __SYSREG(0xd860000a, u8)/* RTC control reg A */ +#define RTCRA_RS 0x0f /* periodic timer interrupt cycle setting */ +#define RTCRA_RS_NONE 0x00 /* - off */ +#define RTCRA_RS_3_90625ms 0x01 /* - 3.90625ms (1/256s) */ +#define RTCRA_RS_7_8125ms 0x02 /* - 7.8125ms (1/128s) */ +#define RTCRA_RS_122_070us 0x03 /* - 122.070us (1/8192s) */ +#define RTCRA_RS_244_141us 0x04 /* - 244.141us (1/4096s) */ +#define RTCRA_RS_488_281us 0x05 /* - 488.281us (1/2048s) */ +#define RTCRA_RS_976_5625us 0x06 /* - 976.5625us (1/1024s) */ +#define RTCRA_RS_1_953125ms 0x07 /* - 1.953125ms (1/512s) */ +#define RTCRA_RS_3_90624ms 0x08 /* - 3.90624ms (1/256s) */ +#define RTCRA_RS_7_8125ms_b 0x09 /* - 7.8125ms (1/128s) */ +#define RTCRA_RS_15_625ms 0x0a /* - 15.625ms (1/64s) */ +#define RTCRA_RS_31_25ms 0x0b /* - 31.25ms (1/32s) */ +#define RTCRA_RS_62_5ms 0x0c /* - 62.5ms (1/16s) */ +#define RTCRA_RS_125ms 0x0d /* - 125ms (1/8s) */ +#define RTCRA_RS_250ms 0x0e /* - 250ms (1/4s) */ +#define RTCRA_RS_500ms 0x0f /* - 500ms (1/2s) */ +#define RTCRA_DVR 0x40 /* divider reset */ +#define RTCRA_UIP 0x80 /* clock update flag */ + +#define RTCRB __SYSREG(0xd860000b, u8) /* RTC control reg B */ +#define RTCRB_DSE 0x01 /* daylight savings time enable */ +#define RTCRB_TM 0x02 /* time format */ +#define RTCRB_TM_12HR 0x00 /* - 12 hour format */ +#define RTCRB_TM_24HR 0x02 /* - 24 hour format */ +#define RTCRB_DM 0x04 /* numeric value format */ +#define RTCRB_DM_BCD 0x00 /* - BCD */ +#define RTCRB_DM_BINARY 0x04 /* - binary */ +#define RTCRB_UIE 0x10 /* update interrupt disable */ +#define RTCRB_AIE 0x20 /* alarm interrupt disable */ +#define RTCRB_PIE 0x40 /* periodic interrupt disable */ +#define RTCRB_SET 0x80 /* clock update enable */ + +#define RTSRC __SYSREG(0xd860000c, u8) /* RTC status reg C */ +#define RTSRC_UF 0x10 /* update end interrupt flag */ +#define RTSRC_AF 0x20 /* alarm interrupt flag */ +#define RTSRC_PF 0x40 /* periodic interrupt flag */ +#define RTSRC_IRQF 0x80 /* interrupt flag */ + +#define RTIRQ 32 +#define RTICR GxICR(RTIRQ) + +/* + * MC146818 RTC compatibility defs for the MN10300 on-chip RTC + */ +#define RTC_PORT(x) 0xd8600000 +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ + +#define CMOS_READ(addr) __SYSREG(0xd8600000 + (addr), u8) +#define CMOS_WRITE(val, addr) \ + do { __SYSREG(0xd8600000 + (addr), u8) = val; } while (0) + +#define RTC_IRQ RTIRQ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_RTC_REGS_H */ diff --git a/arch/mn10300/include/asm/rtc.h b/arch/mn10300/include/asm/rtc.h new file mode 100644 index 0000000..c295194 --- /dev/null +++ b/arch/mn10300/include/asm/rtc.h @@ -0,0 +1,41 @@ +/* MN10300 Real time clock definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_RTC_H +#define _ASM_RTC_H + +#ifdef CONFIG_MN10300_RTC + +#include <linux/init.h> + +extern void check_rtc_time(void); +extern void __init calibrate_clock(void); +extern unsigned long __init get_initial_rtc_time(void); + +#else /* !CONFIG_MN10300_RTC */ + +static inline void check_rtc_time(void) +{ +} + +static inline void calibrate_clock(void) +{ +} + +static inline unsigned long get_initial_rtc_time(void) +{ + return 0; +} + +#endif /* !CONFIG_MN10300_RTC */ + +#include <asm-generic/rtc.h> + +#endif /* _ASM_RTC_H */ diff --git a/arch/mn10300/include/asm/scatterlist.h b/arch/mn10300/include/asm/scatterlist.h new file mode 100644 index 0000000..6753590 --- /dev/null +++ b/arch/mn10300/include/asm/scatterlist.h @@ -0,0 +1,55 @@ +/* MN10300 Scatterlist definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SCATTERLIST_H +#define _ASM_SCATTERLIST_H + +#include <asm/types.h> + +/* + * Drivers must set either ->address or (preferred) page and ->offset + * to indicate where data must be transferred to/from. + * + * Using page is recommended since it handles highmem data as well as + * low mem. ->address is restricted to data which has a virtual mapping, and + * it will go away in the future. Updating to page can be automated very + * easily -- something like + * + * sg->address = some_ptr; + * + * can be rewritten as + * + * sg_set_page(virt_to_page(some_ptr)); + * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK; + * + * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens + */ +struct scatterlist { +#ifdef CONFIG_DEBUG_SG + unsigned long sg_magic; +#endif + unsigned long page_link; + unsigned int offset; /* for highmem, page offset */ + dma_addr_t dma_address; + unsigned int length; +}; + +#define ISA_DMA_THRESHOLD (0x00ffffff) + +/* + * These macros should be used after a pci_map_sg call has been done + * to get bus addresses of each of the SG entries and their lengths. + * You should only work with the number of sg entries pci_map_sg + * returns. + */ +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->length) + +#endif /* _ASM_SCATTERLIST_H */ diff --git a/arch/mn10300/include/asm/sections.h b/arch/mn10300/include/asm/sections.h new file mode 100644 index 0000000..2b8c516 --- /dev/null +++ b/arch/mn10300/include/asm/sections.h @@ -0,0 +1 @@ +#include <asm-generic/sections.h> diff --git a/arch/mn10300/include/asm/sembuf.h b/arch/mn10300/include/asm/sembuf.h new file mode 100644 index 0000000..301f3f9 --- /dev/null +++ b/arch/mn10300/include/asm/sembuf.h @@ -0,0 +1,25 @@ +#ifndef _ASM_SEMBUF_H +#define _ASM_SEMBUF_H + +/* + * The semid64_ds structure for MN10300 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _ASM_SEMBUF_H */ diff --git a/arch/mn10300/include/asm/serial-regs.h b/arch/mn10300/include/asm/serial-regs.h new file mode 100644 index 0000000..6498469 --- /dev/null +++ b/arch/mn10300/include/asm/serial-regs.h @@ -0,0 +1,160 @@ +/* MN10300 on-board serial port module registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_SERIAL_REGS_H +#define _ASM_SERIAL_REGS_H + +#include <asm/cpu-regs.h> +#include <asm/intctl-regs.h> + +#ifdef __KERNEL__ + +/* serial port 0 */ +#define SC0CTR __SYSREG(0xd4002000, u16) /* control reg */ +#define SC01CTR_CK 0x0007 /* clock source select */ +#define SC0CTR_CK_TM8UFLOW_8 0x0000 /* - 1/8 timer 8 underflow (serial port 0 only) */ +#define SC1CTR_CK_TM9UFLOW_8 0x0000 /* - 1/8 timer 9 underflow (serial port 1 only) */ +#define SC01CTR_CK_IOCLK_8 0x0001 /* - 1/8 IOCLK */ +#define SC01CTR_CK_IOCLK_32 0x0002 /* - 1/32 IOCLK */ +#define SC0CTR_CK_TM2UFLOW_2 0x0003 /* - 1/2 timer 2 underflow (serial port 0 only) */ +#define SC1CTR_CK_TM3UFLOW_2 0x0003 /* - 1/2 timer 3 underflow (serial port 1 only) */ +#define SC0CTR_CK_TM0UFLOW_8 0x0004 /* - 1/8 timer 1 underflow (serial port 0 only) */ +#define SC1CTR_CK_TM1UFLOW_8 0x0004 /* - 1/8 timer 2 underflow (serial port 1 only) */ +#define SC0CTR_CK_TM2UFLOW_8 0x0005 /* - 1/8 timer 2 underflow (serial port 0 only) */ +#define SC1CTR_CK_TM3UFLOW_8 0x0005 /* - 1/8 timer 3 underflow (serial port 1 only) */ +#define SC01CTR_CK_EXTERN_8 0x0006 /* - 1/8 external closk */ +#define SC01CTR_CK_EXTERN 0x0007 /* - external closk */ +#define SC01CTR_STB 0x0008 /* stop bit select */ +#define SC01CTR_STB_1BIT 0x0000 /* - 1 stop bit */ +#define SC01CTR_STB_2BIT 0x0008 /* - 2 stop bits */ +#define SC01CTR_PB 0x0070 /* parity bit select */ +#define SC01CTR_PB_NONE 0x0000 /* - no parity */ +#define SC01CTR_PB_FIXED0 0x0040 /* - fixed at 0 */ +#define SC01CTR_PB_FIXED1 0x0050 /* - fixed at 1 */ +#define SC01CTR_PB_EVEN 0x0060 /* - even parity */ +#define SC01CTR_PB_ODD 0x0070 /* - odd parity */ +#define SC01CTR_CLN 0x0080 /* character length */ +#define SC01CTR_CLN_7BIT 0x0000 /* - 7 bit chars */ +#define SC01CTR_CLN_8BIT 0x0080 /* - 8 bit chars */ +#define SC01CTR_TOE 0x0100 /* T input output enable */ +#define SC01CTR_OD 0x0200 /* bit order select */ +#define SC01CTR_OD_LSBFIRST 0x0000 /* - LSB first */ +#define SC01CTR_OD_MSBFIRST 0x0200 /* - MSB first */ +#define SC01CTR_MD 0x0c00 /* mode select */ +#define SC01CTR_MD_STST_SYNC 0x0000 /* - start-stop synchronous */ +#define SC01CTR_MD_CLOCK_SYNC1 0x0400 /* - clock synchronous 1 */ +#define SC01CTR_MD_I2C 0x0800 /* - I2C mode */ +#define SC01CTR_MD_CLOCK_SYNC2 0x0c00 /* - clock synchronous 2 */ +#define SC01CTR_IIC 0x1000 /* I2C mode select */ +#define SC01CTR_BKE 0x2000 /* break transmit enable */ +#define SC01CTR_RXE 0x4000 /* receive enable */ +#define SC01CTR_TXE 0x8000 /* transmit enable */ + +#define SC0ICR __SYSREG(0xd4002004, u8) /* interrupt control reg */ +#define SC01ICR_DMD 0x80 /* output data mode */ +#define SC01ICR_TD 0x20 /* transmit DMA trigger cause */ +#define SC01ICR_TI 0x10 /* transmit interrupt cause */ +#define SC01ICR_RES 0x04 /* receive error select */ +#define SC01ICR_RI 0x01 /* receive interrupt cause */ + +#define SC0TXB __SYSREG(0xd4002008, u8) /* transmit buffer reg */ +#define SC0RXB __SYSREG(0xd4002009, u8) /* receive buffer reg */ + +#define SC0STR __SYSREG(0xd400200c, u16) /* status reg */ +#define SC01STR_OEF 0x0001 /* overrun error found */ +#define SC01STR_PEF 0x0002 /* parity error found */ +#define SC01STR_FEF 0x0004 /* framing error found */ +#define SC01STR_RBF 0x0010 /* receive buffer status */ +#define SC01STR_TBF 0x0020 /* transmit buffer status */ +#define SC01STR_RXF 0x0040 /* receive status */ +#define SC01STR_TXF 0x0080 /* transmit status */ +#define SC01STR_STF 0x0100 /* I2C start sequence found */ +#define SC01STR_SPF 0x0200 /* I2C stop sequence found */ + +#define SC0RXIRQ 20 /* timer 0 Receive IRQ */ +#define SC0TXIRQ 21 /* timer 0 Transmit IRQ */ + +#define SC0RXICR GxICR(SC0RXIRQ) /* serial 0 receive intr ctrl reg */ +#define SC0TXICR GxICR(SC0TXIRQ) /* serial 0 transmit intr ctrl reg */ + +/* serial port 1 */ +#define SC1CTR __SYSREG(0xd4002010, u16) /* serial port 1 control */ +#define SC1ICR __SYSREG(0xd4002014, u8) /* interrupt control reg */ +#define SC1TXB __SYSREG(0xd4002018, u8) /* transmit buffer reg */ +#define SC1RXB __SYSREG(0xd4002019, u8) /* receive buffer reg */ +#define SC1STR __SYSREG(0xd400201c, u16) /* status reg */ + +#define SC1RXIRQ 22 /* timer 1 Receive IRQ */ +#define SC1TXIRQ 23 /* timer 1 Transmit IRQ */ + +#define SC1RXICR GxICR(SC1RXIRQ) /* serial 1 receive intr ctrl reg */ +#define SC1TXICR GxICR(SC1TXIRQ) /* serial 1 transmit intr ctrl reg */ + +/* serial port 2 */ +#define SC2CTR __SYSREG(0xd4002020, u16) /* control reg */ +#define SC2CTR_CK 0x0003 /* clock source select */ +#define SC2CTR_CK_TM10UFLOW 0x0000 /* - timer 10 underflow */ +#define SC2CTR_CK_TM2UFLOW 0x0001 /* - timer 2 underflow */ +#define SC2CTR_CK_EXTERN 0x0002 /* - external closk */ +#define SC2CTR_CK_TM3UFLOW 0x0003 /* - timer 3 underflow */ +#define SC2CTR_STB 0x0008 /* stop bit select */ +#define SC2CTR_STB_1BIT 0x0000 /* - 1 stop bit */ +#define SC2CTR_STB_2BIT 0x0008 /* - 2 stop bits */ +#define SC2CTR_PB 0x0070 /* parity bit select */ +#define SC2CTR_PB_NONE 0x0000 /* - no parity */ +#define SC2CTR_PB_FIXED0 0x0040 /* - fixed at 0 */ +#define SC2CTR_PB_FIXED1 0x0050 /* - fixed at 1 */ +#define SC2CTR_PB_EVEN 0x0060 /* - even parity */ +#define SC2CTR_PB_ODD 0x0070 /* - odd parity */ +#define SC2CTR_CLN 0x0080 /* character length */ +#define SC2CTR_CLN_7BIT 0x0000 /* - 7 bit chars */ +#define SC2CTR_CLN_8BIT 0x0080 /* - 8 bit chars */ +#define SC2CTR_TWE 0x0100 /* transmit wait enable (enable XCTS control) */ +#define SC2CTR_OD 0x0200 /* bit order select */ +#define SC2CTR_OD_LSBFIRST 0x0000 /* - LSB first */ +#define SC2CTR_OD_MSBFIRST 0x0200 /* - MSB first */ +#define SC2CTR_TWS 0x1000 /* transmit wait select */ +#define SC2CTR_TWS_XCTS_HIGH 0x0000 /* - interrupt TX when XCTS high */ +#define SC2CTR_TWS_XCTS_LOW 0x1000 /* - interrupt TX when XCTS low */ +#define SC2CTR_BKE 0x2000 /* break transmit enable */ +#define SC2CTR_RXE 0x4000 /* receive enable */ +#define SC2CTR_TXE 0x8000 /* transmit enable */ + +#define SC2ICR __SYSREG(0xd4002024, u8) /* interrupt control reg */ +#define SC2ICR_TD 0x20 /* transmit DMA trigger cause */ +#define SC2ICR_TI 0x10 /* transmit interrupt cause */ +#define SC2ICR_RES 0x04 /* receive error select */ +#define SC2ICR_RI 0x01 /* receive interrupt cause */ + +#define SC2TXB __SYSREG(0xd4002018, u8) /* transmit buffer reg */ +#define SC2RXB __SYSREG(0xd4002019, u8) /* receive buffer reg */ +#define SC2STR __SYSREG(0xd400201c, u8) /* status reg */ +#define SC2STR_OEF 0x0001 /* overrun error found */ +#define SC2STR_PEF 0x0002 /* parity error found */ +#define SC2STR_FEF 0x0004 /* framing error found */ +#define SC2STR_CTS 0x0008 /* XCTS input pin status (0 means high) */ +#define SC2STR_RBF 0x0010 /* receive buffer status */ +#define SC2STR_TBF 0x0020 /* transmit buffer status */ +#define SC2STR_RXF 0x0040 /* receive status */ +#define SC2STR_TXF 0x0080 /* transmit status */ + +#define SC2TIM __SYSREG(0xd400202d, u8) /* status reg */ + +#define SC2RXIRQ 24 /* serial 2 Receive IRQ */ +#define SC2TXIRQ 25 /* serial 2 Transmit IRQ */ + +#define SC2RXICR GxICR(SC2RXIRQ) /* serial 2 receive intr ctrl reg */ +#define SC2TXICR GxICR(SC2TXIRQ) /* serial 2 transmit intr ctrl reg */ + + +#endif /* __KERNEL__ */ + +#endif /* _ASM_SERIAL_REGS_H */ diff --git a/arch/mn10300/include/asm/serial.h b/arch/mn10300/include/asm/serial.h new file mode 100644 index 0000000..a29445c --- /dev/null +++ b/arch/mn10300/include/asm/serial.h @@ -0,0 +1,36 @@ +/* Standard UART definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +/* + * The ASB2305 has an 18.432 MHz clock the UART + */ +#define BASE_BAUD (18432000 / 16) + +/* Standard COM flags (except for COM4, because of the 8514 problem) */ +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF +#endif + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define FOURPORT_FLAGS ASYNC_FOURPORT +#define ACCENT_FLAGS 0 +#define BOCA_FLAGS 0 +#define HUB6_FLAGS 0 +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE +#endif + +#include <unit/serial.h> diff --git a/arch/mn10300/include/asm/setup.h b/arch/mn10300/include/asm/setup.h new file mode 100644 index 0000000..08356c8 --- /dev/null +++ b/arch/mn10300/include/asm/setup.h @@ -0,0 +1,17 @@ +/* MN10300 Setup declarations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SETUP_H +#define _ASM_SETUP_H + +extern void __init unit_setup(void); +extern void __init unit_init_IRQ(void); + +#endif /* _ASM_SETUP_H */ diff --git a/arch/mn10300/include/asm/shmbuf.h b/arch/mn10300/include/asm/shmbuf.h new file mode 100644 index 0000000..8f300cc --- /dev/null +++ b/arch/mn10300/include/asm/shmbuf.h @@ -0,0 +1,42 @@ +#ifndef _ASM_SHMBUF_H +#define _ASM_SHMBUF_H + +/* + * The shmid64_ds structure for MN10300 architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _ASM_SHMBUF_H */ diff --git a/arch/mn10300/include/asm/shmparam.h b/arch/mn10300/include/asm/shmparam.h new file mode 100644 index 0000000..ab666ed --- /dev/null +++ b/arch/mn10300/include/asm/shmparam.h @@ -0,0 +1,6 @@ +#ifndef _ASM_SHMPARAM_H +#define _ASM_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _ASM_SHMPARAM_H */ diff --git a/arch/mn10300/include/asm/sigcontext.h b/arch/mn10300/include/asm/sigcontext.h new file mode 100644 index 0000000..4de3aff --- /dev/null +++ b/arch/mn10300/include/asm/sigcontext.h @@ -0,0 +1,52 @@ +/* MN10300 Userspace signal context + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SIGCONTEXT_H +#define _ASM_SIGCONTEXT_H + +struct fpucontext { + /* Regular FPU environment */ + unsigned long fs[32]; /* fpu registers */ + unsigned long fpcr; /* fpu control register */ +}; + +struct sigcontext { + unsigned long d0; + unsigned long d1; + unsigned long d2; + unsigned long d3; + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; + unsigned long e0; + unsigned long e1; + unsigned long e2; + unsigned long e3; + unsigned long e4; + unsigned long e5; + unsigned long e6; + unsigned long e7; + unsigned long lar; + unsigned long lir; + unsigned long mdr; + unsigned long mcvf; + unsigned long mcrl; + unsigned long mcrh; + unsigned long mdrq; + unsigned long sp; + unsigned long epsw; + unsigned long pc; + struct fpucontext *fpucontext; + unsigned long oldmask; +}; + + +#endif /* _ASM_SIGCONTEXT_H */ diff --git a/arch/mn10300/include/asm/siginfo.h b/arch/mn10300/include/asm/siginfo.h new file mode 100644 index 0000000..0815d29 --- /dev/null +++ b/arch/mn10300/include/asm/siginfo.h @@ -0,0 +1 @@ +#include <asm-generic/siginfo.h> diff --git a/arch/mn10300/include/asm/signal.h b/arch/mn10300/include/asm/signal.h new file mode 100644 index 0000000..e98817c --- /dev/null +++ b/arch/mn10300/include/asm/signal.h @@ -0,0 +1,171 @@ +/* MN10300 Signal definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SIGNAL_H +#define _ASM_SIGNAL_H + +#include <linux/types.h> + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX (_NSIG-1) + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001U +#define SA_NOCLDWAIT 0x00000002U +#define SA_SIGINFO 0x00000004U +#define SA_ONSTACK 0x08000000U +#define SA_RESTART 0x10000000U +#define SA_NODEFER 0x40000000U +#define SA_RESETHAND 0x80000000U + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +#define SA_RESTORER 0x04000000 + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include <asm-generic/signal.h> + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + __sigrestore_t sa_restorer; +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + __sigrestore_t sa_restorer; + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +#include <asm/sigcontext.h> + + +struct pt_regs; +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_SIGNAL_H */ diff --git a/arch/mn10300/include/asm/smp.h b/arch/mn10300/include/asm/smp.h new file mode 100644 index 0000000..4eb8c61 --- /dev/null +++ b/arch/mn10300/include/asm/smp.h @@ -0,0 +1,18 @@ +/* MN10300 SMP support + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SMP_H +#define _ASM_SMP_H + +#ifdef CONFIG_SMP +#error SMP not yet supported for MN10300 +#endif + +#endif diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h new file mode 100644 index 0000000..fb5daf4 --- /dev/null +++ b/arch/mn10300/include/asm/socket.h @@ -0,0 +1,60 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include <asm/sockios.h> + +/* For setsockopt(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_SNDBUFFORCE 32 +#define SO_RCVBUFFORCE 33 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 + +#define SO_PEERSEC 31 +#define SO_PASSSEC 34 +#define SO_TIMESTAMPNS 35 +#define SCM_TIMESTAMPNS SO_TIMESTAMPNS + +#define SO_MARK 36 + +#define SO_TIMESTAMPING 37 +#define SCM_TIMESTAMPING SO_TIMESTAMPING + +#endif /* _ASM_SOCKET_H */ diff --git a/arch/mn10300/include/asm/sockios.h b/arch/mn10300/include/asm/sockios.h new file mode 100644 index 0000000..b03043a --- /dev/null +++ b/arch/mn10300/include/asm/sockios.h @@ -0,0 +1,13 @@ +#ifndef _ASM_SOCKIOS_H +#define _ASM_SOCKIOS_H + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp */ +#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + +#endif /* _ASM_SOCKIOS_H */ diff --git a/arch/mn10300/include/asm/spinlock.h b/arch/mn10300/include/asm/spinlock.h new file mode 100644 index 0000000..4bf9c8b --- /dev/null +++ b/arch/mn10300/include/asm/spinlock.h @@ -0,0 +1,16 @@ +/* MN10300 spinlock support + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SPINLOCK_H +#define _ASM_SPINLOCK_H + +#error SMP spinlocks not implemented for MN10300 + +#endif /* _ASM_SPINLOCK_H */ diff --git a/arch/mn10300/include/asm/stat.h b/arch/mn10300/include/asm/stat.h new file mode 100644 index 0000000..63ff837 --- /dev/null +++ b/arch/mn10300/include/asm/stat.h @@ -0,0 +1,78 @@ +#ifndef _ASM_STAT_H +#define _ASM_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned long st_rdev; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long st_atime_nsec; + unsigned long st_mtime; + unsigned long st_mtime_nsec; + unsigned long st_ctime; + unsigned long st_ctime_nsec; + unsigned long __unused4; + unsigned long __unused5; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned long long st_dev; + unsigned char __pad0[4]; + +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* future possible st_blocks high bits */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned int st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; + + unsigned long long st_ino; +}; + +#define STAT_HAVE_NSEC 1 + +#endif /* _ASM_STAT_H */ diff --git a/arch/mn10300/include/asm/statfs.h b/arch/mn10300/include/asm/statfs.h new file mode 100644 index 0000000..0b91fe1 --- /dev/null +++ b/arch/mn10300/include/asm/statfs.h @@ -0,0 +1 @@ +#include <asm-generic/statfs.h> diff --git a/arch/mn10300/include/asm/string.h b/arch/mn10300/include/asm/string.h new file mode 100644 index 0000000..47dbd43 --- /dev/null +++ b/arch/mn10300/include/asm/string.h @@ -0,0 +1,32 @@ +/* MN10300 Optimised string functions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Modified by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_STRING_H +#define _ASM_STRING_H + +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMMOVE + +extern void *memset(void *dest, int ch, size_t count); +extern void *memcpy(void *dest, const void *src, size_t count); +extern void *memmove(void *dest, const void *src, size_t count); + + +extern void __struct_cpy_bug(void); +#define struct_cpy(x, y) \ +({ \ + if (sizeof(*(x)) != sizeof(*(y))) \ + __struct_cpy_bug; \ + memcpy(x, y, sizeof(*(x))); \ +}) + +#endif /* _ASM_STRING_H */ diff --git a/arch/mn10300/include/asm/swab.h b/arch/mn10300/include/asm/swab.h new file mode 100644 index 0000000..bd818a8 --- /dev/null +++ b/arch/mn10300/include/asm/swab.h @@ -0,0 +1,42 @@ +/* MN10300 Byte-order primitive construction + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SWAB_H +#define _ASM_SWAB_H + +#include <linux/types.h> + +#ifdef __GNUC__ + +static inline __attribute__((const)) +__u32 __arch_swab32(__u32 x) +{ + __u32 ret; + asm("swap %1,%0" : "=r" (ret) : "r" (x)); + return ret; +} +#define __arch_swab32 __arch_swab32 + +static inline __attribute__((const)) +__u16 __arch_swab16(__u16 x) +{ + __u16 ret; + asm("swaph %1,%0" : "=r" (ret) : "r" (x)); + return ret; +} +#define __arch_swab32 __arch_swab32 + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __SWAB_64_THRU_32__ +#endif + +#endif /* __GNUC__ */ + +#endif /* _ASM_SWAB_H */ diff --git a/arch/mn10300/include/asm/system.h b/arch/mn10300/include/asm/system.h new file mode 100644 index 0000000..8214fb7 --- /dev/null +++ b/arch/mn10300/include/asm/system.h @@ -0,0 +1,237 @@ +/* MN10300 System definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_SYSTEM_H +#define _ASM_SYSTEM_H + +#include <asm/cpu-regs.h> + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +#include <linux/kernel.h> + +struct task_struct; +struct thread_struct; + +extern asmlinkage +struct task_struct *__switch_to(struct thread_struct *prev, + struct thread_struct *next, + struct task_struct *prev_task); + +/* context switching is now performed out-of-line in switch_to.S */ +#define switch_to(prev, next, last) \ +do { \ + current->thread.wchan = (u_long) __builtin_return_address(0); \ + (last) = __switch_to(&(prev)->thread, &(next)->thread, (prev)); \ + mb(); \ + current->thread.wchan = 0; \ +} while (0) + +#define arch_align_stack(x) (x) + +#define nop() asm volatile ("nop") + +#endif /* !__ASSEMBLY__ */ + +/* + * Force strict CPU ordering. + * And yes, this is required on UP too when we're talking + * to devices. + * + * For now, "wmb()" doesn't actually do anything, as all + * Intel CPU's follow what Intel calls a *Processor Order*, + * in which all writes are seen in the program order even + * outside the CPU. + * + * I expect future Intel CPU's to have a weaker ordering, + * but I'd also expect them to finally get their act together + * and add some real memory barriers if so. + * + * Some non intel clones support out of order store. wmb() ceases to be a + * nop for these. + */ + +#define mb() asm volatile ("": : :"memory") +#define rmb() mb() +#define wmb() asm volatile ("": : :"memory") + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#endif + +#define set_mb(var, value) do { var = value; mb(); } while (0) +#define set_wmb(var, value) do { var = value; wmb(); } while (0) + +#define read_barrier_depends() do {} while (0) +#define smp_read_barrier_depends() do {} while (0) + +/*****************************************************************************/ +/* + * interrupt control + * - "disabled": run in IM1/2 + * - level 0 - GDB stub + * - level 1 - virtual serial DMA (if present) + * - level 5 - normal interrupt priority + * - level 6 - timer interrupt + * - "enabled": run in IM7 + */ +#ifdef CONFIG_MN10300_TTYSM +#define MN10300_CLI_LEVEL EPSW_IM_2 +#else +#define MN10300_CLI_LEVEL EPSW_IM_1 +#endif + +#define local_save_flags(x) \ +do { \ + typecheck(unsigned long, x); \ + asm volatile( \ + " mov epsw,%0 \n" \ + : "=d"(x) \ + ); \ +} while (0) + +#define local_irq_disable() \ +do { \ + asm volatile( \ + " and %0,epsw \n" \ + " or %1,epsw \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + : \ + : "i"(~EPSW_IM), "i"(EPSW_IE | MN10300_CLI_LEVEL) \ + ); \ +} while (0) + +#define local_irq_save(x) \ +do { \ + local_save_flags(x); \ + local_irq_disable(); \ +} while (0) + +/* + * we make sure local_irq_enable() doesn't cause priority inversion + */ +#ifndef __ASSEMBLY__ + +extern unsigned long __mn10300_irq_enabled_epsw; + +#endif + +#define local_irq_enable() \ +do { \ + unsigned long tmp; \ + \ + asm volatile( \ + " mov epsw,%0 \n" \ + " and %1,%0 \n" \ + " or %2,%0 \n" \ + " mov %0,epsw \n" \ + : "=&d"(tmp) \ + : "i"(~EPSW_IM), "r"(__mn10300_irq_enabled_epsw) \ + ); \ +} while (0) + +#define local_irq_restore(x) \ +do { \ + typecheck(unsigned long, x); \ + asm volatile( \ + " mov %0,epsw \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + : \ + : "d"(x) \ + : "memory", "cc" \ + ); \ +} while (0) + +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + (flags & EPSW_IM) <= MN10300_CLI_LEVEL; \ +}) + +/* hook to save power by halting the CPU + * - called from the idle loop + * - must reenable interrupts (which takes three instruction cycles to complete) + */ +#define safe_halt() \ +do { \ + asm volatile(" or %0,epsw \n" \ + " nop \n" \ + " nop \n" \ + " bset %2,(%1) \n" \ + : \ + : "i"(EPSW_IE|EPSW_IM), "n"(&CPUM), "i"(CPUM_SLEEP)\ + : "cc" \ + ); \ +} while (0) + +#define STI or EPSW_IE|EPSW_IM,epsw +#define CLI and ~EPSW_IM,epsw; or EPSW_IE|MN10300_CLI_LEVEL,epsw; nop; nop; nop + +/*****************************************************************************/ +/* + * MN10300 doesn't actually have an exchange instruction + */ +#ifndef __ASSEMBLY__ + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((struct __xchg_dummy *)(x)) + +static inline +unsigned long __xchg(volatile unsigned long *m, unsigned long val) +{ + unsigned long retval; + unsigned long flags; + + local_irq_save(flags); + retval = *m; + *m = val; + local_irq_restore(flags); + return retval; +} + +#define xchg(ptr, v) \ + ((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr), \ + (unsigned long)(v))) + +static inline unsigned long __cmpxchg(volatile unsigned long *m, + unsigned long old, unsigned long new) +{ + unsigned long retval; + unsigned long flags; + + local_irq_save(flags); + retval = *m; + if (retval == old) + *m = new; + local_irq_restore(flags); + return retval; +} + +#define cmpxchg(ptr, o, n) \ + ((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \ + (unsigned long)(o), \ + (unsigned long)(n))) + +#endif /* !__ASSEMBLY__ */ + +#endif /* __KERNEL__ */ +#endif /* _ASM_SYSTEM_H */ diff --git a/arch/mn10300/include/asm/termbits.h b/arch/mn10300/include/asm/termbits.h new file mode 100644 index 0000000..eb2b0dc --- /dev/null +++ b/arch/mn10300/include/asm/termbits.h @@ -0,0 +1,200 @@ +#ifndef _ASM_TERMBITS_H +#define _ASM_TERMBITS_H + +#include <linux/posix_types.h> + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define BOTHER 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CTVB 004000000000 /* VisioBraille Terminal flow control */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* _ASM_TERMBITS_H */ diff --git a/arch/mn10300/include/asm/termios.h b/arch/mn10300/include/asm/termios.h new file mode 100644 index 0000000..dd7cf61 --- /dev/null +++ b/arch/mn10300/include/asm/termios.h @@ -0,0 +1,92 @@ +#ifndef _ASM_TERMIOS_H +#define _ASM_TERMIOS_H + +#include <asm/termbits.h> +#include <asm/ioctls.h> + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ + unsigned short __tmp; \ + get_user(__tmp, &(termio)->x); \ + *(unsigned short *) &(termios)->x = __tmp; \ +} + +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) \ + copy_from_user(k, u, sizeof(struct termios2)) +#define kernel_termios_to_user_termios(u, k) \ + copy_to_user(u, k, sizeof(struct termios2)) +#define user_termios_to_kernel_termios_1(k, u) \ + copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios_1(u, k) \ + copy_to_user(u, k, sizeof(struct termios)) + +#endif /* _ASM_TERMIOS_H */ diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h new file mode 100644 index 0000000..78a3881 --- /dev/null +++ b/arch/mn10300/include/asm/thread_info.h @@ -0,0 +1,170 @@ +/* MN10300 Low-level thread information + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#include <asm/page.h> + +#ifndef __ASSEMBLY__ +#include <asm/processor.h> +#endif + +#define PREEMPT_ACTIVE 0x10000000 + +#ifdef CONFIG_4KSTACKS +#define THREAD_SIZE (4096) +#else +#define THREAD_SIZE (8192) +#endif + +#define STACK_WARN (THREAD_SIZE / 8) + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants + * must also be changed + */ +#ifndef __ASSEMBLY__ + +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + __u32 cpu; /* current CPU */ + __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ + + mm_segment_t addr_limit; /* thread address space: + 0-0xBFFFFFFF for user-thead + 0-0xFFFFFFFF for kernel-thread + */ + struct restart_block restart_block; + + __u8 supervisor_stack[0]; +}; + +#else /* !__ASSEMBLY__ */ + +#ifndef __ASM_OFFSETS_H__ +#include <asm/asm-offsets.h> +#endif + +#endif + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#ifndef __ASSEMBLY__ + +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) +#define init_uregs \ + ((struct pt_regs *) \ + ((unsigned long) init_stack + THREAD_SIZE - sizeof(struct pt_regs))) + +extern struct thread_info *__current_ti; + +/* how to get the thread information struct from C */ +static inline __attribute__((const)) +struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + asm("mov sp,%0\n" + "and %1,%0\n" + : "=d" (ti) + : "i" (~(THREAD_SIZE - 1)) + : "cc"); + return ti; +} + +/* how to get the current stack pointer from C */ +static inline unsigned long current_stack_pointer(void) +{ + unsigned long sp; + asm("mov sp,%0; ":"=r" (sp)); + return sp; +} + +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + +/* thread information allocation */ +#ifdef CONFIG_DEBUG_STACK_USAGE +#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL) +#else +#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) +#endif + +#define free_thread_info(ti) kfree((ti)) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) + +#else /* !__ASSEMBLY__ */ + +#ifndef __VMLINUX_LDS__ +/* how to get the thread information struct from ASM */ +.macro GET_THREAD_INFO reg + mov sp,\reg + and -THREAD_SIZE,\reg +.endm +#endif +#endif + +/* + * thread information flags + * - these are process state flags that various assembly files may need to + * access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ +#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ +#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_MEMDIE 17 /* OOM killer killed process */ +#define TIF_FREEZE 18 /* freezing for suspend */ + +#define _TIF_SYSCALL_TRACE +(1 << TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME +(1 << TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING +(1 << TIF_SIGPENDING) +#define _TIF_NEED_RESCHED +(1 << TIF_NEED_RESCHED) +#define _TIF_SINGLESTEP +(1 << TIF_SINGLESTEP) +#define _TIF_RESTORE_SIGMASK +(1 << TIF_RESTORE_SIGMASK) +#define _TIF_POLLING_NRFLAG +(1 << TIF_POLLING_NRFLAG) +#define _TIF_FREEZE +(1 << TIF_FREEZE) + +#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ +#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff --git a/arch/mn10300/include/asm/timer-regs.h b/arch/mn10300/include/asm/timer-regs.h new file mode 100644 index 0000000..1d883b7 --- /dev/null +++ b/arch/mn10300/include/asm/timer-regs.h @@ -0,0 +1,293 @@ +/* AM33v2 on-board timer module registers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_TIMER_REGS_H +#define _ASM_TIMER_REGS_H + +#include <asm/cpu-regs.h> +#include <asm/intctl-regs.h> + +#ifdef __KERNEL__ + +/* timer prescalar control */ +#define TMPSCNT __SYSREG(0xd4003071, u8) /* timer prescaler control */ +#define TMPSCNT_ENABLE 0x80 /* timer prescaler enable */ +#define TMPSCNT_DISABLE 0x00 /* timer prescaler disable */ + +/* 8 bit timers */ +#define TM0MD __SYSREG(0xd4003000, u8) /* timer 0 mode register */ +#define TM0MD_SRC 0x07 /* timer source */ +#define TM0MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM0MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM0MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM0MD_SRC_TM2IO 0x03 /* - TM2IO pin input */ +#define TM0MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM0MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM0MD_SRC_TM0IO 0x07 /* - TM0IO pin input */ +#define TM0MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM0MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM1MD __SYSREG(0xd4003001, u8) /* timer 1 mode register */ +#define TM1MD_SRC 0x07 /* timer source */ +#define TM1MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM1MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM1MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM1MD_SRC_TM0CASCADE 0x03 /* - cascade with timer 0 */ +#define TM1MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM1MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM1MD_SRC_TM1IO 0x07 /* - TM1IO pin input */ +#define TM1MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM1MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM2MD __SYSREG(0xd4003002, u8) /* timer 2 mode register */ +#define TM2MD_SRC 0x07 /* timer source */ +#define TM2MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM2MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM2MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM2MD_SRC_TM1CASCADE 0x03 /* - cascade with timer 1 */ +#define TM2MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM2MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM2MD_SRC_TM2IO 0x07 /* - TM2IO pin input */ +#define TM2MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM2MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM3MD __SYSREG(0xd4003003, u8) /* timer 3 mode register */ +#define TM3MD_SRC 0x07 /* timer source */ +#define TM3MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM3MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM3MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM3MD_SRC_TM1CASCADE 0x03 /* - cascade with timer 2 */ +#define TM3MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM3MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM3MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM3MD_SRC_TM3IO 0x07 /* - TM3IO pin input */ +#define TM3MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM3MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM01MD __SYSREG(0xd4003000, u16) /* timer 0:1 mode register */ + +#define TM0BR __SYSREG(0xd4003010, u8) /* timer 0 base register */ +#define TM1BR __SYSREG(0xd4003011, u8) /* timer 1 base register */ +#define TM2BR __SYSREG(0xd4003012, u8) /* timer 2 base register */ +#define TM3BR __SYSREG(0xd4003013, u8) /* timer 3 base register */ +#define TM01BR __SYSREG(0xd4003010, u16) /* timer 0:1 base register */ + +#define TM0BC __SYSREGC(0xd4003020, u8) /* timer 0 binary counter */ +#define TM1BC __SYSREGC(0xd4003021, u8) /* timer 1 binary counter */ +#define TM2BC __SYSREGC(0xd4003022, u8) /* timer 2 binary counter */ +#define TM3BC __SYSREGC(0xd4003023, u8) /* timer 3 binary counter */ +#define TM01BC __SYSREGC(0xd4003020, u16) /* timer 0:1 binary counter */ + +#define TM0IRQ 2 /* timer 0 IRQ */ +#define TM1IRQ 3 /* timer 1 IRQ */ +#define TM2IRQ 4 /* timer 2 IRQ */ +#define TM3IRQ 5 /* timer 3 IRQ */ + +#define TM0ICR GxICR(TM0IRQ) /* timer 0 uflow intr ctrl reg */ +#define TM1ICR GxICR(TM1IRQ) /* timer 1 uflow intr ctrl reg */ +#define TM2ICR GxICR(TM2IRQ) /* timer 2 uflow intr ctrl reg */ +#define TM3ICR GxICR(TM3IRQ) /* timer 3 uflow intr ctrl reg */ + +/* 16-bit timers 4,5 & 7-11 */ +#define TM4MD __SYSREG(0xd4003080, u8) /* timer 4 mode register */ +#define TM4MD_SRC 0x07 /* timer source */ +#define TM4MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM4MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM4MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM4MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM4MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM4MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM4MD_SRC_TM4IO 0x07 /* - TM4IO pin input */ +#define TM4MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM4MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM5MD __SYSREG(0xd4003082, u8) /* timer 5 mode register */ +#define TM5MD_SRC 0x07 /* timer source */ +#define TM5MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM5MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM5MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM5MD_SRC_TM4CASCADE 0x03 /* - cascade with timer 4 */ +#define TM5MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM5MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM5MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM5MD_SRC_TM5IO 0x07 /* - TM5IO pin input */ +#define TM5MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM5MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM7MD __SYSREG(0xd4003086, u8) /* timer 7 mode register */ +#define TM7MD_SRC 0x07 /* timer source */ +#define TM7MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM7MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM7MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM7MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM7MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM7MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM7MD_SRC_TM7IO 0x07 /* - TM7IO pin input */ +#define TM7MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM7MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM8MD __SYSREG(0xd4003088, u8) /* timer 8 mode register */ +#define TM8MD_SRC 0x07 /* timer source */ +#define TM8MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM8MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM8MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM8MD_SRC_TM7CASCADE 0x03 /* - cascade with timer 7 */ +#define TM8MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM8MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM8MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM8MD_SRC_TM8IO 0x07 /* - TM8IO pin input */ +#define TM8MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM8MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM9MD __SYSREG(0xd400308a, u8) /* timer 9 mode register */ +#define TM9MD_SRC 0x07 /* timer source */ +#define TM9MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM9MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM9MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM9MD_SRC_TM8CASCADE 0x03 /* - cascade with timer 8 */ +#define TM9MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM9MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM9MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM9MD_SRC_TM9IO 0x07 /* - TM9IO pin input */ +#define TM9MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM9MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM10MD __SYSREG(0xd400308c, u8) /* timer 10 mode register */ +#define TM10MD_SRC 0x07 /* timer source */ +#define TM10MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM10MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM10MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM10MD_SRC_TM9CASCADE 0x03 /* - cascade with timer 9 */ +#define TM10MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM10MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM10MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM10MD_SRC_TM10IO 0x07 /* - TM10IO pin input */ +#define TM10MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM10MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM11MD __SYSREG(0xd400308e, u8) /* timer 11 mode register */ +#define TM11MD_SRC 0x07 /* timer source */ +#define TM11MD_SRC_IOCLK 0x00 /* - IOCLK */ +#define TM11MD_SRC_IOCLK_8 0x01 /* - 1/8 IOCLK */ +#define TM11MD_SRC_IOCLK_32 0x02 /* - 1/32 IOCLK */ +#define TM11MD_SRC_TM7CASCADE 0x03 /* - cascade with timer 7 */ +#define TM11MD_SRC_TM0UFLOW 0x04 /* - timer 0 underflow */ +#define TM11MD_SRC_TM1UFLOW 0x05 /* - timer 1 underflow */ +#define TM11MD_SRC_TM2UFLOW 0x06 /* - timer 2 underflow */ +#define TM11MD_SRC_TM11IO 0x07 /* - TM11IO pin input */ +#define TM11MD_INIT_COUNTER 0x40 /* initialize TMnBC = TMnBR */ +#define TM11MD_COUNT_ENABLE 0x80 /* timer count enable */ + +#define TM4BR __SYSREG(0xd4003090, u16) /* timer 4 base register */ +#define TM5BR __SYSREG(0xd4003092, u16) /* timer 5 base register */ +#define TM7BR __SYSREG(0xd4003096, u16) /* timer 7 base register */ +#define TM8BR __SYSREG(0xd4003098, u16) /* timer 8 base register */ +#define TM9BR __SYSREG(0xd400309a, u16) /* timer 9 base register */ +#define TM10BR __SYSREG(0xd400309c, u16) /* timer 10 base register */ +#define TM11BR __SYSREG(0xd400309e, u16) /* timer 11 base register */ +#define TM45BR __SYSREG(0xd4003090, u32) /* timer 4:5 base register */ + +#define TM4BC __SYSREG(0xd40030a0, u16) /* timer 4 binary counter */ +#define TM5BC __SYSREG(0xd40030a2, u16) /* timer 5 binary counter */ +#define TM45BC __SYSREG(0xd40030a0, u32) /* timer 4:5 binary counter */ + +#define TM7BC __SYSREG(0xd40030a6, u16) /* timer 7 binary counter */ +#define TM8BC __SYSREG(0xd40030a8, u16) /* timer 8 binary counter */ +#define TM9BC __SYSREG(0xd40030aa, u16) /* timer 9 binary counter */ +#define TM10BC __SYSREG(0xd40030ac, u16) /* timer 10 binary counter */ +#define TM11BC __SYSREG(0xd40030ae, u16) /* timer 11 binary counter */ + +#define TM4IRQ 6 /* timer 4 IRQ */ +#define TM5IRQ 7 /* timer 5 IRQ */ +#define TM7IRQ 11 /* timer 7 IRQ */ +#define TM8IRQ 12 /* timer 8 IRQ */ +#define TM9IRQ 13 /* timer 9 IRQ */ +#define TM10IRQ 14 /* timer 10 IRQ */ +#define TM11IRQ 15 /* timer 11 IRQ */ + +#define TM4ICR GxICR(TM4IRQ) /* timer 4 uflow intr ctrl reg */ +#define TM5ICR GxICR(TM5IRQ) /* timer 5 uflow intr ctrl reg */ +#define TM7ICR GxICR(TM7IRQ) /* timer 7 uflow intr ctrl reg */ +#define TM8ICR GxICR(TM8IRQ) /* timer 8 uflow intr ctrl reg */ +#define TM9ICR GxICR(TM9IRQ) /* timer 9 uflow intr ctrl reg */ +#define TM10ICR GxICR(TM10IRQ) /* timer 10 uflow intr ctrl reg */ +#define TM11ICR GxICR(TM11IRQ) /* timer 11 uflow intr ctrl reg */ + +/* 16-bit timer 6 */ +#define TM6MD __SYSREG(0xd4003084, u16) /* timer6 mode register */ +#define TM6MD_SRC 0x0007 /* timer source */ +#define TM6MD_SRC_IOCLK 0x0000 /* - IOCLK */ +#define TM6MD_SRC_IOCLK_8 0x0001 /* - 1/8 IOCLK */ +#define TM6MD_SRC_IOCLK_32 0x0002 /* - 1/32 IOCLK */ +#define TM6MD_SRC_TM0UFLOW 0x0004 /* - timer 0 underflow */ +#define TM6MD_SRC_TM1UFLOW 0x0005 /* - timer 1 underflow */ +#define TM6MD_SRC_TM6IOB_BOTH 0x0006 /* - TM6IOB pin input (both edges) */ +#define TM6MD_SRC_TM6IOB_SINGLE 0x0007 /* - TM6IOB pin input (single edge) */ +#define TM6MD_CLR_ENABLE 0x0010 /* clear count enable */ +#define TM6MD_ONESHOT_ENABLE 0x0040 /* oneshot count */ +#define TM6MD_TRIG_ENABLE 0x0080 /* TM6IOB pin trigger enable */ +#define TM6MD_PWM 0x3800 /* PWM output mode */ +#define TM6MD_PWM_DIS 0x0000 /* - disabled */ +#define TM6MD_PWM_10BIT 0x1000 /* - 10 bits mode */ +#define TM6MD_PWM_11BIT 0x1800 /* - 11 bits mode */ +#define TM6MD_PWM_12BIT 0x3000 /* - 12 bits mode */ +#define TM6MD_PWM_14BIT 0x3800 /* - 14 bits mode */ +#define TM6MD_INIT_COUNTER 0x4000 /* initialize TMnBC to zero */ +#define TM6MD_COUNT_ENABLE 0x8000 /* timer count enable */ + +#define TM6MDA __SYSREG(0xd40030b4, u8) /* timer6 cmp/cap A mode reg */ +#define TM6MDA_OUT 0x07 /* output select */ +#define TM6MDA_OUT_SETA_RESETB 0x00 /* - set at match A, reset at match B */ +#define TM6MDA_OUT_SETA_RESETOV 0x01 /* - set at match A, reset at overflow */ +#define TM6MDA_OUT_SETA 0x02 /* - set at match A */ +#define TM6MDA_OUT_RESETA 0x03 /* - reset at match A */ +#define TM6MDA_OUT_TOGGLE 0x04 /* - toggle on match A */ +#define TM6MDA_MODE 0xc0 /* compare A register mode */ +#define TM6MDA_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */ +#define TM6MDA_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */ +#define TM6MDA_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */ +#define TM6MDA_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */ +#define TM6MDA_EDGE 0x20 /* compare A edge select */ +#define TM6MDA_EDGE_FALLING 0x00 /* capture on falling edge */ +#define TM6MDA_EDGE_RISING 0x20 /* capture on rising edge */ +#define TM6MDA_CAPTURE_ENABLE 0x10 /* capture enable */ + +#define TM6MDB __SYSREG(0xd40030b5, u8) /* timer6 cmp/cap B mode reg */ +#define TM6MDB_OUT 0x07 /* output select */ +#define TM6MDB_OUT_SETB_RESETA 0x00 /* - set at match B, reset at match A */ +#define TM6MDB_OUT_SETB_RESETOV 0x01 /* - set at match B */ +#define TM6MDB_OUT_RESETB 0x03 /* - reset at match B */ +#define TM6MDB_OUT_TOGGLE 0x04 /* - toggle on match B */ +#define TM6MDB_MODE 0xc0 /* compare B register mode */ +#define TM6MDB_MODE_CMP_SINGLE 0x00 /* - compare, single buffer mode */ +#define TM6MDB_MODE_CMP_DOUBLE 0x40 /* - compare, double buffer mode */ +#define TM6MDB_MODE_CAP_S_EDGE 0x80 /* - capture, single edge mode */ +#define TM6MDB_MODE_CAP_D_EDGE 0xc0 /* - capture, double edge mode */ +#define TM6MDB_EDGE 0x20 /* compare B edge select */ +#define TM6MDB_EDGE_FALLING 0x00 /* capture on falling edge */ +#define TM6MDB_EDGE_RISING 0x20 /* capture on rising edge */ +#define TM6MDB_CAPTURE_ENABLE 0x10 /* capture enable */ + +#define TM6CA __SYSREG(0xd40030c4, u16) /* timer6 cmp/capture reg A */ +#define TM6CB __SYSREG(0xd40030d4, u16) /* timer6 cmp/capture reg B */ +#define TM6BC __SYSREG(0xd40030a4, u16) /* timer6 binary counter */ + +#define TM6IRQ 6 /* timer 6 IRQ */ +#define TM6AIRQ 9 /* timer 6A IRQ */ +#define TM6BIRQ 10 /* timer 6B IRQ */ + +#define TM6ICR GxICR(TM6IRQ) /* timer 6 uflow intr ctrl reg */ +#define TM6AICR GxICR(TM6AIRQ) /* timer 6A intr control reg */ +#define TM6BICR GxICR(TM6BIRQ) /* timer 6B intr control reg */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_TIMER_REGS_H */ diff --git a/arch/mn10300/include/asm/timex.h b/arch/mn10300/include/asm/timex.h new file mode 100644 index 0000000..8d031f9 --- /dev/null +++ b/arch/mn10300/include/asm/timex.h @@ -0,0 +1,33 @@ +/* MN10300 Architecture time management specifications + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_TIMEX_H +#define _ASM_TIMEX_H + +#include <asm/hardirq.h> +#include <unit/timex.h> + +#define TICK_SIZE (tick_nsec / 1000) + +#define CLOCK_TICK_RATE 1193180 /* Underlying HZ - this should probably be set + * to something appropriate, but what? */ + +extern cycles_t cacheflush_time; + +#ifdef __KERNEL__ + +static inline cycles_t get_cycles(void) +{ + return read_timestamp_counter(); +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_TIMEX_H */ diff --git a/arch/mn10300/include/asm/tlb.h b/arch/mn10300/include/asm/tlb.h new file mode 100644 index 0000000..65d232b --- /dev/null +++ b/arch/mn10300/include/asm/tlb.h @@ -0,0 +1,34 @@ +/* MN10300 TLB definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_TLB_H +#define _ASM_TLB_H + +#include <asm/tlbflush.h> + +extern void check_pgt_cache(void); + +/* + * we don't need any special per-pte or per-vma handling... + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +/* + * .. because we flush the whole mm when it fills up + */ +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + +/* for now, just use the generic stuff */ +#include <asm-generic/tlb.h> + +#endif /* _ASM_TLB_H */ diff --git a/arch/mn10300/include/asm/tlbflush.h b/arch/mn10300/include/asm/tlbflush.h new file mode 100644 index 0000000..e023986 --- /dev/null +++ b/arch/mn10300/include/asm/tlbflush.h @@ -0,0 +1,80 @@ +/* MN10300 TLB flushing functions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_TLBFLUSH_H +#define _ASM_TLBFLUSH_H + +#include <asm/processor.h> + +#define __flush_tlb() \ +do { \ + int w; \ + __asm__ __volatile__ \ + (" mov %1,%0 \n" \ + " or %2,%0 \n" \ + " mov %0,%1 \n" \ + : "=d"(w) \ + : "m"(MMUCTR), "i"(MMUCTR_IIV|MMUCTR_DIV) \ + : "memory" \ + ); \ +} while (0) + +#define __flush_tlb_all() __flush_tlb() +#define __flush_tlb_one(addr) __flush_tlb() + + +/* + * TLB flushing: + * + * - flush_tlb() flushes the current mm struct TLBs + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(mm, start, end) flushes a range of pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables + */ +#define flush_tlb_all() \ +do { \ + preempt_disable(); \ + __flush_tlb_all(); \ + preempt_enable(); \ +} while (0) + +#define flush_tlb_mm(mm) \ +do { \ + preempt_disable(); \ + __flush_tlb_all(); \ + preempt_enable(); \ +} while (0) + +#define flush_tlb_range(vma, start, end) \ +do { \ + unsigned long __s __attribute__((unused)) = (start); \ + unsigned long __e __attribute__((unused)) = (end); \ + preempt_disable(); \ + __flush_tlb_all(); \ + preempt_enable(); \ +} while (0) + + +#define __flush_tlb_global() flush_tlb_all() +#define flush_tlb() flush_tlb_all() +#define flush_tlb_kernel_range(start, end) \ +do { \ + unsigned long __s __attribute__((unused)) = (start); \ + unsigned long __e __attribute__((unused)) = (end); \ + flush_tlb_all(); \ +} while (0) + +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); + +#define flush_tlb_pgtables(mm, start, end) do {} while (0) + +#endif /* _ASM_TLBFLUSH_H */ diff --git a/arch/mn10300/include/asm/topology.h b/arch/mn10300/include/asm/topology.h new file mode 100644 index 0000000..5428f33 --- /dev/null +++ b/arch/mn10300/include/asm/topology.h @@ -0,0 +1 @@ +#include <asm-generic/topology.h> diff --git a/arch/mn10300/include/asm/types.h b/arch/mn10300/include/asm/types.h new file mode 100644 index 0000000..7b9f010 --- /dev/null +++ b/arch/mn10300/include/asm/types.h @@ -0,0 +1,38 @@ +/* MN10300 Basic type definitions + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_TYPES_H +#define _ASM_TYPES_H + +#include <asm-generic/int-ll64.h> + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +#endif /* __ASSEMBLY__ */ + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#define BITS_PER_LONG 32 + +#ifndef __ASSEMBLY__ + +/* Dma addresses are 32-bits wide. */ +typedef u32 dma_addr_t; + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_TYPES_H */ diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h new file mode 100644 index 0000000..8a3a4dd --- /dev/null +++ b/arch/mn10300/include/asm/uaccess.h @@ -0,0 +1,490 @@ +/* MN10300 userspace access functions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UACCESS_H +#define _ASM_UACCESS_H + +/* + * User space memory access functions + */ +#include <linux/sched.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/errno.h> + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* + * The fs value determines whether argument validity checking should be + * performed or not. If get_fs() == USER_DS, checking is performed, with + * get_fs() == KERNEL_DS, checking is bypassed. + * + * For historical reasons, these macros are grossly misnamed. + */ + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + +#define KERNEL_XDS MAKE_MM_SEG(0xBFFFFFFF) +#define KERNEL_DS MAKE_MM_SEG(0x9FFFFFFF) +#define USER_DS MAKE_MM_SEG(TASK_SIZE) + +#define get_ds() (KERNEL_DS) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) +#define __kernel_ds_p() (current_thread_info()->addr_limit.seg == 0x9FFFFFFF) + +#define segment_eq(a, b) ((a).seg == (b).seg) + +#define __addr_ok(addr) \ + ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) + +/* + * check that a range of addresses falls within the current address limit + */ +static inline int ___range_ok(unsigned long addr, unsigned int size) +{ + int flag = 1, tmp; + + asm(" add %3,%1 \n" /* set C-flag if addr + size > 4Gb */ + " bcs 0f \n" + " cmp %4,%1 \n" /* jump if addr+size>limit (error) */ + " bhi 0f \n" + " clr %0 \n" /* mark okay */ + "0: \n" + : "=r"(flag), "=&r"(tmp) + : "1"(addr), "ir"(size), + "r"(current_thread_info()->addr_limit.seg), "0"(flag) + : "cc" + ); + + return flag; +} + +#define __range_ok(addr, size) ___range_ok((unsigned long)(addr), (u32)(size)) + +#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) +#define __access_ok(addr, size) (__range_ok((addr), (size)) == 0) + +static inline int verify_area(int type, const void *addr, unsigned long size) +{ + return access_ok(type, addr, size) ? 0 : -EFAULT; +} + + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern int fixup_exception(struct pt_regs *regs); + +#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr))) +#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr))) + +/* + * The "__xxx" versions do not do address space checking, useful when + * doing multiple accesses to the same area (the user has to do the + * checks by hand with "access_ok()") + */ +#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr))) +#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr))) + +/* + * The "xxx_ret" versions return constant specified in third argument, if + * something bad happens. These macros can be optimized for the + * case of just returning from the function xxx_ret is used. + */ + +#define put_user_ret(x, ptr, ret) \ + ({ if (put_user((x), (ptr))) return (ret); }) +#define get_user_ret(x, ptr, ret) \ + ({ if (get_user((x), (ptr))) return (ret); }) +#define __put_user_ret(x, ptr, ret) \ + ({ if (__put_user((x), (ptr))) return (ret); }) +#define __get_user_ret(x, ptr, ret) \ + ({ if (__get_user((x), (ptr))) return (ret); }) + +struct __large_struct { unsigned long buf[100]; }; +#define __m(x) (*(struct __large_struct *)(x)) + +#define __get_user_nocheck(x, ptr, size) \ +({ \ + __typeof(*(ptr)) __gu_val; \ + unsigned long __gu_addr; \ + int __gu_err; \ + __gu_addr = (unsigned long) (ptr); \ + switch (size) { \ + case 1: __get_user_asm("bu"); break; \ + case 2: __get_user_asm("hu"); break; \ + case 4: __get_user_asm("" ); break; \ + default: __get_user_unknown(); break; \ + } \ + x = (__typeof__(*(ptr))) __gu_val; \ + __gu_err; \ +}) + +#define __get_user_check(x, ptr, size) \ +({ \ + __typeof__(*(ptr)) __gu_val; \ + unsigned long __gu_addr; \ + int __gu_err; \ + __gu_addr = (unsigned long) (ptr); \ + if (likely(__access_ok(__gu_addr,size))) { \ + switch (size) { \ + case 1: __get_user_asm("bu"); break; \ + case 2: __get_user_asm("hu"); break; \ + case 4: __get_user_asm("" ); break; \ + default: __get_user_unknown(); break; \ + } \ + } \ + else { \ + __gu_err = -EFAULT; \ + __gu_val = 0; \ + } \ + x = (__typeof__(*(ptr))) __gu_val; \ + __gu_err; \ +}) + +#define __get_user_asm(INSN) \ +({ \ + asm volatile( \ + "1:\n" \ + " mov"INSN" %2,%1\n" \ + " mov 0,%0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3:\n\t" \ + " mov %3,%0\n" \ + " jmp 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "=&r" (__gu_err), "=&r" (__gu_val) \ + : "m" (__m(__gu_addr)), "i" (-EFAULT)); \ +}) + +extern int __get_user_unknown(void); + +#define __put_user_nocheck(x, ptr, size) \ +({ \ + union { \ + __typeof__(*(ptr)) val; \ + u32 bits[2]; \ + } __pu_val; \ + unsigned long __pu_addr; \ + int __pu_err; \ + __pu_val.val = (x); \ + __pu_addr = (unsigned long) (ptr); \ + switch (size) { \ + case 1: __put_user_asm("bu"); break; \ + case 2: __put_user_asm("hu"); break; \ + case 4: __put_user_asm("" ); break; \ + case 8: __put_user_asm8(); break; \ + default: __pu_err = __put_user_unknown(); break; \ + } \ + __pu_err; \ +}) + +#define __put_user_check(x, ptr, size) \ +({ \ + union { \ + __typeof__(*(ptr)) val; \ + u32 bits[2]; \ + } __pu_val; \ + unsigned long __pu_addr; \ + int __pu_err; \ + __pu_val.val = (x); \ + __pu_addr = (unsigned long) (ptr); \ + if (likely(__access_ok(__pu_addr, size))) { \ + switch (size) { \ + case 1: __put_user_asm("bu"); break; \ + case 2: __put_user_asm("hu"); break; \ + case 4: __put_user_asm("" ); break; \ + case 8: __put_user_asm8(); break; \ + default: __pu_err = __put_user_unknown(); break; \ + } \ + } \ + else { \ + __pu_err = -EFAULT; \ + } \ + __pu_err; \ +}) + +#define __put_user_asm(INSN) \ +({ \ + asm volatile( \ + "1:\n" \ + " mov"INSN" %1,%2\n" \ + " mov 0,%0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3:\n" \ + " mov %3,%0\n" \ + " jmp 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "=&r" (__pu_err) \ + : "r" (__pu_val.val), "m" (__m(__pu_addr)), \ + "i" (-EFAULT) \ + ); \ +}) + +#define __put_user_asm8() \ +({ \ + asm volatile( \ + "1: mov %1,%3 \n" \ + "2: mov %2,%4 \n" \ + " mov 0,%0 \n" \ + "3: \n" \ + " .section .fixup,\"ax\" \n" \ + "4: \n" \ + " mov %5,%0 \n" \ + " jmp 3b \n" \ + " .previous \n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4 \n" \ + " .long 1b, 4b \n" \ + " .long 2b, 4b \n" \ + " .previous \n" \ + : "=&r" (__pu_err) \ + : "r" (__pu_val.bits[0]), "r" (__pu_val.bits[1]), \ + "m" (__m(__pu_addr)), "m" (__m(__pu_addr+4)), \ + "i" (-EFAULT) \ + ); \ +}) + +extern int __put_user_unknown(void); + + +/* + * Copy To/From Userspace + */ +/* Generic arbitrary sized copy. */ +#define __copy_user(to, from, size) \ +do { \ + if (size) { \ + void *__to = to; \ + const void *__from = from; \ + int w; \ + asm volatile( \ + "0: movbu (%0),%3;\n" \ + "1: movbu %3,(%1);\n" \ + " inc %0;\n" \ + " inc %1;\n" \ + " add -1,%2;\n" \ + " bne 0b;\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3: jmp 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,3b\n" \ + " .previous\n" \ + : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ + : "0"(__from), "1"(__to), "2"(size) \ + : "memory"); \ + } \ +} while (0) + +#define __copy_user_zeroing(to, from, size) \ +do { \ + if (size) { \ + void *__to = to; \ + const void *__from = from; \ + int w; \ + asm volatile( \ + "0: movbu (%0),%3;\n" \ + "1: movbu %3,(%1);\n" \ + " inc %0;\n" \ + " inc %1;\n" \ + " add -1,%2;\n" \ + " bne 0b;\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + "3:\n" \ + " mov %2,%0\n" \ + " clr %3\n" \ + "4: movbu %3,(%1);\n" \ + " inc %1;\n" \ + " add -1,%2;\n" \ + " bne 4b;\n" \ + " mov %0,%2\n" \ + " jmp 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,3b\n" \ + " .previous\n" \ + : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ + : "0"(__from), "1"(__to), "2"(size) \ + : "memory"); \ + } \ +} while (0) + +/* We let the __ versions of copy_from/to_user inline, because they're often + * used in fast paths and have only a small space overhead. + */ +static inline +unsigned long __generic_copy_from_user_nocheck(void *to, const void *from, + unsigned long n) +{ + __copy_user_zeroing(to, from, n); + return n; +} + +static inline +unsigned long __generic_copy_to_user_nocheck(void *to, const void *from, + unsigned long n) +{ + __copy_user(to, from, n); + return n; +} + + +#if 0 +#error don't use - these macros don't increment to & from pointers +/* Optimize just a little bit when we know the size of the move. */ +#define __constant_copy_user(to, from, size) \ +do { \ + asm volatile( \ + " mov %0,a0;\n" \ + "0: movbu (%1),d3;\n" \ + "1: movbu d3,(%2);\n" \ + " add -1,a0;\n" \ + " bne 0b;\n" \ + "2:;" \ + ".section .fixup,\"ax\"\n" \ + "3: jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : \ + : "d"(size), "d"(to), "d"(from) \ + : "d3", "a0"); \ +} while (0) + +/* Optimize just a little bit when we know the size of the move. */ +#define __constant_copy_user_zeroing(to, from, size) \ +do { \ + asm volatile( \ + " mov %0,a0;\n" \ + "0: movbu (%1),d3;\n" \ + "1: movbu d3,(%2);\n" \ + " add -1,a0;\n" \ + " bne 0b;\n" \ + "2:;" \ + ".section .fixup,\"ax\"\n" \ + "3: jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .balign 4\n" \ + " .long 0b,3b\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : \ + : "d"(size), "d"(to), "d"(from) \ + : "d3", "a0"); \ +} while (0) + +static inline +unsigned long __constant_copy_to_user(void *to, const void *from, + unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + __constant_copy_user(to, from, n); + return n; +} + +static inline +unsigned long __constant_copy_from_user(void *to, const void *from, + unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + __constant_copy_user_zeroing(to, from, n); + return n; +} + +static inline +unsigned long __constant_copy_to_user_nocheck(void *to, const void *from, + unsigned long n) +{ + __constant_copy_user(to, from, n); + return n; +} + +static inline +unsigned long __constant_copy_from_user_nocheck(void *to, const void *from, + unsigned long n) +{ + __constant_copy_user_zeroing(to, from, n); + return n; +} +#endif + +extern unsigned long __generic_copy_to_user(void __user *, const void *, + unsigned long); +extern unsigned long __generic_copy_from_user(void *, const void __user *, + unsigned long); + +#define __copy_to_user_inatomic(to, from, n) \ + __generic_copy_to_user_nocheck((to), (from), (n)) +#define __copy_from_user_inatomic(to, from, n) \ + __generic_copy_from_user_nocheck((to), (from), (n)) + +#define __copy_to_user(to, from, n) \ +({ \ + might_sleep(); \ + __copy_to_user_inatomic((to), (from), (n)); \ +}) + +#define __copy_from_user(to, from, n) \ +({ \ + might_sleep(); \ + __copy_from_user_inatomic((to), (from), (n)); \ +}) + + +#define copy_to_user(to, from, n) __generic_copy_to_user((to), (from), (n)) +#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n)) + +extern long strncpy_from_user(char *dst, const char __user *src, long count); +extern long __strncpy_from_user(char *dst, const char __user *src, long count); +extern long strnlen_user(const char __user *str, long n); +#define strlen_user(str) strnlen_user(str, ~0UL >> 1) +extern unsigned long clear_user(void __user *mem, unsigned long len); +extern unsigned long __clear_user(void __user *mem, unsigned long len); + +#endif /* _ASM_UACCESS_H */ diff --git a/arch/mn10300/include/asm/ucontext.h b/arch/mn10300/include/asm/ucontext.h new file mode 100644 index 0000000..fcab5c1 --- /dev/null +++ b/arch/mn10300/include/asm/ucontext.h @@ -0,0 +1,22 @@ +/* MN10300 User context + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UCONTEXT_H +#define _ASM_UCONTEXT_H + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif /* _ASM_UCONTEXT_H */ diff --git a/arch/mn10300/include/asm/unaligned.h b/arch/mn10300/include/asm/unaligned.h new file mode 100644 index 0000000..0df6713 --- /dev/null +++ b/arch/mn10300/include/asm/unaligned.h @@ -0,0 +1,20 @@ +/* MN10300 Unaligned memory access handling + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_MN10300_UNALIGNED_H +#define _ASM_MN10300_UNALIGNED_H + +#include <linux/unaligned/access_ok.h> +#include <linux/unaligned/generic.h> + +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le + +#endif /* _ASM_MN10300_UNALIGNED_H */ diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h new file mode 100644 index 0000000..543a4f9 --- /dev/null +++ b/arch/mn10300/include/asm/unistd.h @@ -0,0 +1,390 @@ +/* MN10300 System call number list + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UNISTD_H +#define _ASM_UNISTD_H + +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_lchown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86old 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_vm86 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_chown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_lchown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_chown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_mincore 218 +#define __NR_madvise 219 +#define __NR_madvise1 219 /* delete when C lib stub is removed */ +#define __NR_getdents64 220 +#define __NR_fcntl64 221 +/* 223 is unused */ +#define __NR_gettid 224 +#define __NR_readahead 225 +#define __NR_setxattr 226 +#define __NR_lsetxattr 227 +#define __NR_fsetxattr 228 +#define __NR_getxattr 229 +#define __NR_lgetxattr 230 +#define __NR_fgetxattr 231 +#define __NR_listxattr 232 +#define __NR_llistxattr 233 +#define __NR_flistxattr 234 +#define __NR_removexattr 235 +#define __NR_lremovexattr 236 +#define __NR_fremovexattr 237 +#define __NR_tkill 238 +#define __NR_sendfile64 239 +#define __NR_futex 240 +#define __NR_sched_setaffinity 241 +#define __NR_sched_getaffinity 242 +#define __NR_set_thread_area 243 +#define __NR_get_thread_area 244 +#define __NR_io_setup 245 +#define __NR_io_destroy 246 +#define __NR_io_getevents 247 +#define __NR_io_submit 248 +#define __NR_io_cancel 249 +#define __NR_fadvise64 250 + +#define __NR_exit_group 252 +#define __NR_lookup_dcookie 253 +#define __NR_epoll_create 254 +#define __NR_epoll_ctl 255 +#define __NR_epoll_wait 256 +#define __NR_remap_file_pages 257 +#define __NR_set_tid_address 258 +#define __NR_timer_create 259 +#define __NR_timer_settime (__NR_timer_create+1) +#define __NR_timer_gettime (__NR_timer_create+2) +#define __NR_timer_getoverrun (__NR_timer_create+3) +#define __NR_timer_delete (__NR_timer_create+4) +#define __NR_clock_settime (__NR_timer_create+5) +#define __NR_clock_gettime (__NR_timer_create+6) +#define __NR_clock_getres (__NR_timer_create+7) +#define __NR_clock_nanosleep (__NR_timer_create+8) +#define __NR_statfs64 268 +#define __NR_fstatfs64 269 +#define __NR_tgkill 270 +#define __NR_utimes 271 +#define __NR_fadvise64_64 272 +#define __NR_vserver 273 +#define __NR_mbind 274 +#define __NR_get_mempolicy 275 +#define __NR_set_mempolicy 276 +#define __NR_mq_open 277 +#define __NR_mq_unlink (__NR_mq_open+1) +#define __NR_mq_timedsend (__NR_mq_open+2) +#define __NR_mq_timedreceive (__NR_mq_open+3) +#define __NR_mq_notify (__NR_mq_open+4) +#define __NR_mq_getsetattr (__NR_mq_open+5) +#define __NR_kexec_load 283 +#define __NR_waitid 284 +#define __NR_add_key 286 +#define __NR_request_key 287 +#define __NR_keyctl 288 +#define __NR_cacheflush 289 +#define __NR_ioprio_set 290 +#define __NR_ioprio_get 291 +#define __NR_inotify_init 292 +#define __NR_inotify_add_watch 293 +#define __NR_inotify_rm_watch 294 +#define __NR_migrate_pages 295 +#define __NR_openat 296 +#define __NR_mkdirat 297 +#define __NR_mknodat 298 +#define __NR_fchownat 299 +#define __NR_futimesat 300 +#define __NR_fstatat64 301 +#define __NR_unlinkat 302 +#define __NR_renameat 303 +#define __NR_linkat 304 +#define __NR_symlinkat 305 +#define __NR_readlinkat 306 +#define __NR_fchmodat 307 +#define __NR_faccessat 308 +#define __NR_pselect6 309 +#define __NR_ppoll 310 +#define __NR_unshare 311 +#define __NR_set_robust_list 312 +#define __NR_get_robust_list 313 +#define __NR_splice 314 +#define __NR_sync_file_range 315 +#define __NR_tee 316 +#define __NR_vmsplice 317 +#define __NR_move_pages 318 +#define __NR_getcpu 319 +#define __NR_epoll_pwait 320 +#define __NR_utimensat 321 +#define __NR_signalfd 322 +#define __NR_timerfd_create 323 +#define __NR_eventfd 324 +#define __NR_fallocate 325 +#define __NR_timerfd_settime 326 +#define __NR_timerfd_gettime 327 +#define __NR_signalfd4 328 +#define __NR_eventfd2 329 +#define __NR_epoll_create1 330 +#define __NR_dup3 331 +#define __NR_pipe2 332 +#define __NR_inotify_init1 333 + +#ifdef __KERNEL__ + +#define NR_syscalls 326 + +/* + * specify the deprecated syscalls we want to support on this arch + */ +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#ifndef cond_syscall +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); +#endif + +#endif /* __KERNEL__ */ +#endif /* _ASM_UNISTD_H */ diff --git a/arch/mn10300/include/asm/user.h b/arch/mn10300/include/asm/user.h new file mode 100644 index 0000000..e119390 --- /dev/null +++ b/arch/mn10300/include/asm/user.h @@ -0,0 +1,53 @@ +/* MN10300 User process data + * + * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_USER_H +#define _ASM_USER_H + +#include <asm/page.h> +#include <linux/ptrace.h> + +#ifndef __ASSEMBLY__ +/* + * When the kernel dumps core, it starts by dumping the user struct - this will + * be used by gdb to figure out where the data and stack segments are within + * the file, and what virtual addresses to use. + */ +struct user { + /* We start with the registers, to mimic the way that "memory" is + * returned from the ptrace(3,...) function. + */ + struct pt_regs regs; /* Where the registers are actually stored */ + + /* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + struct user_pt_regs *u_ar0; /* Used by gdb to help find the values for */ + + /* the registers */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ +}; +#endif + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR +(u.start_code) +#define HOST_STACK_END_ADDR +(u.start_stack + u.u_ssize * NBPG) + +#endif /* _ASM_USER_H */ diff --git a/arch/mn10300/include/asm/vga.h b/arch/mn10300/include/asm/vga.h new file mode 100644 index 0000000..0163e50 --- /dev/null +++ b/arch/mn10300/include/asm/vga.h @@ -0,0 +1,17 @@ +/* MN10300 VGA register definitions + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_VGA_H +#define _ASM_VGA_H + + + +#endif /* _ASM_VGA_H */ diff --git a/arch/mn10300/include/asm/xor.h b/arch/mn10300/include/asm/xor.h new file mode 100644 index 0000000..c82eb12 --- /dev/null +++ b/arch/mn10300/include/asm/xor.h @@ -0,0 +1 @@ +#include <asm-generic/xor.h> diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index ceeaaaa..34ab5a2 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S @@ -20,7 +20,7 @@ #include <asm/intctl-regs.h> #include <asm/busctl-regs.h> #include <asm/timer-regs.h> -#include <asm/unit/leds.h> +#include <unit/leds.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/errno.h> diff --git a/arch/mn10300/kernel/gdb-io-serial-low.S b/arch/mn10300/kernel/gdb-io-serial-low.S index c68dcd0..4998b24f 100644 --- a/arch/mn10300/kernel/gdb-io-serial-low.S +++ b/arch/mn10300/kernel/gdb-io-serial-low.S @@ -18,7 +18,7 @@ #include <asm/thread_info.h> #include <asm/frame.inc> #include <asm/intctl-regs.h> -#include <asm/unit/serial.h> +#include <unit/serial.h> .text diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c index 11584c5..ae663dc 100644 --- a/arch/mn10300/kernel/gdb-io-serial.c +++ b/arch/mn10300/kernel/gdb-io-serial.c @@ -22,7 +22,7 @@ #include <asm/gdb-stub.h> #include <asm/exceptions.h> #include <asm/serial-regs.h> -#include <asm/unit/serial.h> +#include <unit/serial.h> /* * initialise the GDB stub diff --git a/arch/mn10300/kernel/gdb-io-ttysm-low.S b/arch/mn10300/kernel/gdb-io-ttysm-low.S index 677c787..060b7cc 100644 --- a/arch/mn10300/kernel/gdb-io-ttysm-low.S +++ b/arch/mn10300/kernel/gdb-io-ttysm-low.S @@ -18,7 +18,7 @@ #include <asm/cpu-regs.h> #include <asm/frame.inc> #include <asm/intctl-regs.h> -#include <asm/unit/serial.h> +#include <unit/serial.h> #include "mn10300-serial.h" .text diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c index e94c25e..a560bbc 100644 --- a/arch/mn10300/kernel/gdb-io-ttysm.c +++ b/arch/mn10300/kernel/gdb-io-ttysm.c @@ -20,7 +20,7 @@ #include <asm/system.h> #include <asm/gdb-stub.h> #include <asm/exceptions.h> -#include <asm/unit/clock.h> +#include <unit/clock.h> #include "mn10300-serial.h" #if defined(CONFIG_GDBSTUB_ON_TTYSM0) diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c index 0ea7482..41b1170 100644 --- a/arch/mn10300/kernel/gdb-stub.c +++ b/arch/mn10300/kernel/gdb-stub.c @@ -136,8 +136,8 @@ #include <asm/cacheflush.h> #include <asm/serial-regs.h> #include <asm/busctl-regs.h> -#include <asm/unit/leds.h> -#include <asm/unit/serial.h> +#include <unit/leds.h> +#include <unit/serial.h> /* define to use F7F7 rather than FF which is subverted by JTAG debugger */ #undef GDBSTUB_USE_F7F7_AS_BREAKPOINT diff --git a/arch/mn10300/kernel/head.S b/arch/mn10300/kernel/head.S index 606bd8c..8a8309f 100644 --- a/arch/mn10300/kernel/head.S +++ b/arch/mn10300/kernel/head.S @@ -17,7 +17,7 @@ #include <asm/pgtable.h> #include <asm/frame.inc> #include <asm/param.h> -#include <asm/unit/serial.h> +#include <unit/serial.h> .section .text.head,"ax" diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c index 50fdb5c..4c3c58e 100644 --- a/arch/mn10300/kernel/irq.c +++ b/arch/mn10300/kernel/irq.c @@ -140,7 +140,7 @@ void __init init_IRQ(void) int irq; for (irq = 0; irq < NR_IRQS; irq++) - if (irq_desc[irq].chip == &no_irq_type) + if (irq_desc[irq].chip == &no_irq_chip) /* due to the PIC latching interrupt requests, even * when the IRQ is disabled, IRQ_PENDING is superfluous * and we can use handle_level_irq() for edge-triggered diff --git a/arch/mn10300/kernel/mn10300-serial-low.S b/arch/mn10300/kernel/mn10300-serial-low.S index ef3f4c1..2244853 100644 --- a/arch/mn10300/kernel/mn10300-serial-low.S +++ b/arch/mn10300/kernel/mn10300-serial-low.S @@ -18,8 +18,8 @@ #include <asm/cpu-regs.h> #include <asm/frame.inc> #include <asm/timer-regs.h> -#include <asm/proc/cache.h> -#include <asm/unit/timex.h> +#include <proc/cache.h> +#include <unit/timex.h> #include "mn10300-serial.h" #define SCxCTR 0x00 diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index 59b9c4b..2fd5966 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c @@ -41,7 +41,7 @@ static const char serial_revdate[] = "2007-11-06"; #include <asm/irq.h> #include <asm/bitops.h> #include <asm/serial-regs.h> -#include <asm/unit/timex.h> +#include <unit/timex.h> #include "mn10300-serial.h" static inline __attribute__((format(printf, 1, 2))) diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c index 2e370d8..f362d9d 100644 --- a/arch/mn10300/kernel/mn10300-watchdog.c +++ b/arch/mn10300/kernel/mn10300-watchdog.c @@ -25,7 +25,7 @@ #include <asm/div64.h> #include <asm/smp.h> #include <asm/gdb-stub.h> -#include <asm/proc/clock.h> +#include <proc/clock.h> static DEFINE_SPINLOCK(watchdog_print_lock); static unsigned int watchdog; diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c index e1d88ab..71414e1 100644 --- a/arch/mn10300/kernel/setup.c +++ b/arch/mn10300/kernel/setup.c @@ -30,7 +30,7 @@ #include <asm/setup.h> #include <asm/io.h> #include <asm/smp.h> -#include <asm/proc/proc.h> +#include <proc/proc.h> #include <asm/busctl-regs.h> #include <asm/fpu.h> #include <asm/sections.h> diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c index fcb9a03..681ad8c 100644 --- a/arch/mn10300/kernel/traps.c +++ b/arch/mn10300/kernel/traps.c @@ -37,7 +37,7 @@ #include <asm/cacheflush.h> #include <asm/cpu-regs.h> #include <asm/busctl-regs.h> -#include <asm/unit/leds.h> +#include <unit/leds.h> #include <asm/fpu.h> #include <asm/gdb-stub.h> #include <asm/sections.h> diff --git a/arch/mn10300/oprofile/Kconfig b/arch/mn10300/oprofile/Kconfig deleted file mode 100644 index 19d3773..0000000 --- a/arch/mn10300/oprofile/Kconfig +++ /dev/null @@ -1,23 +0,0 @@ - -menu "Profiling support" - depends on EXPERIMENTAL - -config PROFILING - bool "Profiling support (EXPERIMENTAL)" - help - Say Y here to enable the extended profiling support mechanisms used - by profilers such as OProfile. - - -config OPROFILE - tristate "OProfile system profiling (EXPERIMENTAL)" - depends on PROFILING - help - OProfile is a profiling system capable of profiling the - whole system, include the kernel, kernel modules, libraries, - and applications. - - If unsure, say N. - -endmenu - diff --git a/arch/mn10300/proc-mn103e010/include/proc/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h new file mode 100644 index 0000000..bdc1f9a --- /dev/null +++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h @@ -0,0 +1,33 @@ +/* MN103E010 Cache specification + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PROC_CACHE_H +#define _ASM_PROC_CACHE_H + +/* L1 cache */ + +#define L1_CACHE_NWAYS 4 /* number of ways in caches */ +#define L1_CACHE_NENTRIES 256 /* number of entries in each way */ +#define L1_CACHE_BYTES 16 /* bytes per entry */ +#define L1_CACHE_SHIFT 4 /* shift for bytes per entry */ +#define L1_CACHE_WAYDISP 0x1000 /* displacement of one way from the next */ + +#define L1_CACHE_TAG_VALID 0x00000001 /* cache tag valid bit */ +#define L1_CACHE_TAG_DIRTY 0x00000008 /* data cache tag dirty bit */ +#define L1_CACHE_TAG_ENTRY 0x00000ff0 /* cache tag entry address mask */ +#define L1_CACHE_TAG_ADDRESS 0xfffff000 /* cache tag line address mask */ + +/* + * specification of the interval between interrupt checking intervals whilst + * managing the cache with the interrupts disabled + */ +#define MN10300_DCACHE_INV_RANGE_INTR_LOG2_INTERVAL 4 + +#endif /* _ASM_PROC_CACHE_H */ diff --git a/arch/mn10300/proc-mn103e010/include/proc/clock.h b/arch/mn10300/proc-mn103e010/include/proc/clock.h new file mode 100644 index 0000000..aa23e14 --- /dev/null +++ b/arch/mn10300/proc-mn103e010/include/proc/clock.h @@ -0,0 +1,18 @@ +/* MN103E010-specific clocks + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_PROC_CLOCK_H +#define _ASM_PROC_CLOCK_H + +#include <unit/clock.h> + +#define MN10300_WDCLK MN10300_IOCLK + +#endif /* _ASM_PROC_CLOCK_H */ diff --git a/arch/mn10300/proc-mn103e010/include/proc/irq.h b/arch/mn10300/proc-mn103e010/include/proc/irq.h new file mode 100644 index 0000000..aa6ee8f --- /dev/null +++ b/arch/mn10300/proc-mn103e010/include/proc/irq.h @@ -0,0 +1,34 @@ +/* MN103E010 On-board interrupt controller numbers + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_PROC_IRQ_H +#define _ASM_PROC_IRQ_H + +#ifdef __KERNEL__ + +#define GxICR_NUM_IRQS 42 + +#define GxICR_NUM_XIRQS 8 + +#define XIRQ0 34 +#define XIRQ1 35 +#define XIRQ2 36 +#define XIRQ3 37 +#define XIRQ4 38 +#define XIRQ5 39 +#define XIRQ6 40 +#define XIRQ7 41 + +#define XIRQ2IRQ(num) (XIRQ0 + num) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_PROC_IRQ_H */ diff --git a/arch/mn10300/proc-mn103e010/include/proc/proc.h b/arch/mn10300/proc-mn103e010/include/proc/proc.h new file mode 100644 index 0000000..22a2b93 --- /dev/null +++ b/arch/mn10300/proc-mn103e010/include/proc/proc.h @@ -0,0 +1,18 @@ +/* MN103E010 Processor description + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_PROC_PROC_H +#define _ASM_PROC_PROC_H + +#define PROCESSOR_VENDOR_NAME "Matsushita" +#define PROCESSOR_MODEL_NAME "mn103e010" + +#endif /* _ASM_PROC_PROC_H */ diff --git a/arch/mn10300/unit-asb2303/include/unit/clock.h b/arch/mn10300/unit-asb2303/include/unit/clock.h new file mode 100644 index 0000000..8b450e9 --- /dev/null +++ b/arch/mn10300/unit-asb2303/include/unit/clock.h @@ -0,0 +1,45 @@ +/* ASB2303-specific clocks + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_UNIT_CLOCK_H +#define _ASM_UNIT_CLOCK_H + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_MN10300_RTC + +extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */ +extern unsigned long mn10300_iobclk; +extern unsigned long mn10300_tsc_per_HZ; + +#define MN10300_IOCLK ((unsigned long)mn10300_ioclk) +/* If this processors has a another clock, uncomment the below. */ +/* #define MN10300_IOBCLK ((unsigned long)mn10300_iobclk) */ + +#else /* !CONFIG_MN10300_RTC */ + +#define MN10300_IOCLK 33333333UL +/* #define MN10300_IOBCLK 66666666UL */ + +#endif /* !CONFIG_MN10300_RTC */ + +#define MN10300_JCCLK MN10300_IOCLK +#define MN10300_TSCCLK MN10300_IOCLK + +#ifdef CONFIG_MN10300_RTC +#define MN10300_TSC_PER_HZ ((unsigned long)mn10300_tsc_per_HZ) +#else /* !CONFIG_MN10300_RTC */ +#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ) +#endif /* !CONFIG_MN10300_RTC */ + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_UNIT_CLOCK_H */ diff --git a/arch/mn10300/unit-asb2303/include/unit/leds.h b/arch/mn10300/unit-asb2303/include/unit/leds.h new file mode 100644 index 0000000..3a7543e --- /dev/null +++ b/arch/mn10300/unit-asb2303/include/unit/leds.h @@ -0,0 +1,43 @@ +/* ASB2303-specific LEDs + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_UNIT_LEDS_H +#define _ASM_UNIT_LEDS_H + +#include <asm/pio-regs.h> +#include <asm/cpu-regs.h> +#include <asm/exceptions.h> + +#define ASB2303_GPIO0DEF __SYSREG(0xDB000000, u32) +#define ASB2303_7SEGLEDS __SYSREG(0xDB000008, u32) + +/* + * use the 7-segment LEDs to indicate states + */ + +/* flip the 7-segment LEDs between "G" and "-" */ +#define mn10300_set_gdbleds(ONOFF) \ +do { \ + ASB2303_7SEGLEDS = (ONOFF) ? 0x85 : 0x7f; \ +} while (0) + +/* indicate double-fault by displaying "d" on the LEDs */ +#define mn10300_set_dbfleds \ + mov 0x43,d0 ; \ + movbu d0,(ASB2303_7SEGLEDS) + +#ifndef __ASSEMBLY__ +extern void peripheral_leds_display_exception(enum exception_code code); +extern void peripheral_leds_led_chase(void); +extern void debug_to_serial(const char *p, int n); +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_UNIT_LEDS_H */ diff --git a/arch/mn10300/unit-asb2303/include/unit/serial.h b/arch/mn10300/unit-asb2303/include/unit/serial.h new file mode 100644 index 0000000..047566c --- /dev/null +++ b/arch/mn10300/unit-asb2303/include/unit/serial.h @@ -0,0 +1,136 @@ +/* ASB2303-specific 8250 serial ports + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_UNIT_SERIAL_H +#define _ASM_UNIT_SERIAL_H + +#include <asm/cpu-regs.h> +#include <proc/irq.h> +#include <linux/serial_reg.h> + +#define SERIAL_PORT0_BASE_ADDRESS 0xA6FB0000 +#define SERIAL_PORT1_BASE_ADDRESS 0xA6FC0000 + +#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */ + +/* + * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports + */ +#ifndef CONFIG_GDBSTUB_ON_TTYSx + +#define SERIAL_PORT_DFNS \ + { \ + .baud_base = BASE_BAUD, \ + .irq = SERIAL_IRQ, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = (u8 *) SERIAL_PORT0_BASE_ADDRESS, \ + .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM, \ + }, \ + { \ + .baud_base = BASE_BAUD, \ + .irq = SERIAL_IRQ, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = (u8 *) SERIAL_PORT1_BASE_ADDRESS, \ + .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM, \ + }, + +#ifndef __ASSEMBLY__ + +static inline void __debug_to_serial(const char *p, int n) +{ +} + +#endif /* !__ASSEMBLY__ */ + +#else /* CONFIG_GDBSTUB_ON_TTYSx */ + +#define SERIAL_PORT_DFNS /* both stolen by gdb-stub because they share an IRQ */ + +#if defined(CONFIG_GDBSTUB_ON_TTYS0) +#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX * 4, u8) +#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 4, u8) +#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 4, u8) +#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 4, u8) +#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 4, u8) +#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 4, u8) +#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 4, u8) +#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 4, u8) +#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8) +#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8) +#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8) +#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 4, u8) +#define GDBPORT_SERIAL_IRQ SERIAL_IRQ + +#elif defined(CONFIG_GDBSTUB_ON_TTYS1) +#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_RX * 4, u8) +#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_TX * 4, u8) +#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_DLL * 4, u8) +#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_DLM * 4, u8) +#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_IER * 4, u8) +#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_IIR * 4, u8) +#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_FCR * 4, u8) +#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_LCR * 4, u8) +#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_MCR * 4, u8) +#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_LSR * 4, u8) +#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_MSR * 4, u8) +#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT1_BASE_ADDRESS + UART_SCR * 4, u8) +#define GDBPORT_SERIAL_IRQ SERIAL_IRQ +#endif + +#ifndef __ASSEMBLY__ + +#define LSR_WAIT_FOR(STATE) \ +do { \ + while (!(GDBPORT_SERIAL_LSR & UART_LSR_##STATE)) {} \ +} while (0) +#define FLOWCTL_WAIT_FOR(LINE) \ +do { \ + while (!(GDBPORT_SERIAL_MSR & UART_MSR_##LINE)) {} \ +} while (0) +#define FLOWCTL_CLEAR(LINE) \ +do { \ + GDBPORT_SERIAL_MCR &= ~UART_MCR_##LINE; \ +} while (0) +#define FLOWCTL_SET(LINE) \ +do { \ + GDBPORT_SERIAL_MCR |= UART_MCR_##LINE; \ +} while (0) +#define FLOWCTL_QUERY(LINE) ({ GDBPORT_SERIAL_MSR & UART_MSR_##LINE; }) + +static inline void __debug_to_serial(const char *p, int n) +{ + char ch; + + FLOWCTL_SET(DTR); + + for (; n > 0; n--) { + LSR_WAIT_FOR(THRE); + FLOWCTL_WAIT_FOR(CTS); + + ch = *p++; + if (ch == 0x0a) { + GDBPORT_SERIAL_TX = 0x0d; + LSR_WAIT_FOR(THRE); + FLOWCTL_WAIT_FOR(CTS); + } + GDBPORT_SERIAL_TX = ch; + } + + FLOWCTL_CLEAR(DTR); +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* CONFIG_GDBSTUB_ON_TTYSx */ + +#endif /* _ASM_UNIT_SERIAL_H */ diff --git a/arch/mn10300/unit-asb2303/include/unit/smc91111.h b/arch/mn10300/unit-asb2303/include/unit/smc91111.h new file mode 100644 index 0000000..dd456e9 --- /dev/null +++ b/arch/mn10300/unit-asb2303/include/unit/smc91111.h @@ -0,0 +1,50 @@ +/* Support for the SMC91C111 NIC on an ASB2303 + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UNIT_SMC91111_H +#define _ASM_UNIT_SMC91111_H + +#include <asm/intctl-regs.h> + +#define SMC91111_BASE 0xAA000300UL +#define SMC91111_BASE_END 0xAA000400UL +#define SMC91111_IRQ XIRQ3 + +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_NOWAIT 1 +#define SMC_IRQ_FLAGS (0) + +#if SMC_CAN_USE_8BIT +#define SMC_inb(a, r) inb((unsigned long) ((a) + (r))) +#define SMC_outb(v, a, r) outb(v, (unsigned long) ((a) + (r))) +#endif + +#if SMC_CAN_USE_16BIT +#define SMC_inw(a, r) inw((unsigned long) ((a) + (r))) +#define SMC_outw(v, a, r) outw(v, (unsigned long) ((a) + (r))) +#define SMC_insw(a, r, p, l) insw((unsigned long) ((a) + (r)), (p), (l)) +#define SMC_outsw(a, r, p, l) outsw((unsigned long) ((a) + (r)), (p), (l)) +#endif + +#if SMC_CAN_USE_32BIT +#define SMC_inl(a, r) inl((unsigned long) ((a) + (r))) +#define SMC_outl(v, a, r) outl(v, (unsigned long) ((a) + (r))) +#define SMC_insl(a, r, p, l) insl((unsigned long) ((a) + (r)), (p), (l)) +#define SMC_outsl(a, r, p, l) outsl((unsigned long) ((a) + (r)), (p), (l)) +#endif + +#define RPC_LSA_DEFAULT RPC_LED_100_10 +#define RPC_LSB_DEFAULT RPC_LED_TX_RX + +#define set_irq_type(irq, type) + +#endif /* _ASM_UNIT_SMC91111_H */ diff --git a/arch/mn10300/unit-asb2303/include/unit/timex.h b/arch/mn10300/unit-asb2303/include/unit/timex.h new file mode 100644 index 0000000..f206b63 --- /dev/null +++ b/arch/mn10300/unit-asb2303/include/unit/timex.h @@ -0,0 +1,135 @@ +/* ASB2303-specific timer specifcations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UNIT_TIMEX_H +#define _ASM_UNIT_TIMEX_H + +#ifndef __ASSEMBLY__ +#include <linux/irq.h> +#endif /* __ASSEMBLY__ */ + +#include <asm/timer-regs.h> +#include <unit/clock.h> + +/* + * jiffies counter specifications + */ + +#define TMJCBR_MAX 0xffff +#define TMJCBC TM01BC + +#define TMJCMD TM01MD +#define TMJCBR TM01BR +#define TMJCIRQ TM1IRQ +#define TMJCICR TM1ICR +#define TMJCICR_LEVEL GxICR_LEVEL_5 + +#ifndef __ASSEMBLY__ + +static inline void startup_jiffies_counter(void) +{ + unsigned rate; + u16 md, t16; + + /* use as little prescaling as possible to avoid losing accuracy */ + md = TM0MD_SRC_IOCLK; + rate = MN10300_JCCLK / HZ; + + if (rate > TMJCBR_MAX) { + md = TM0MD_SRC_IOCLK_8; + rate = MN10300_JCCLK / 8 / HZ; + + if (rate > TMJCBR_MAX) { + md = TM0MD_SRC_IOCLK_32; + rate = MN10300_JCCLK / 32 / HZ; + + if (rate > TMJCBR_MAX) + BUG(); + } + } + + TMJCBR = rate - 1; + t16 = TMJCBR; + + TMJCMD = + md | + TM1MD_SRC_TM0CASCADE << 8 | + TM0MD_INIT_COUNTER | + TM1MD_INIT_COUNTER << 8; + + TMJCMD = + md | + TM1MD_SRC_TM0CASCADE << 8 | + TM0MD_COUNT_ENABLE | + TM1MD_COUNT_ENABLE << 8; + + t16 = TMJCMD; + + TMJCICR |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST; + t16 = TMJCICR; +} + +static inline void shutdown_jiffies_counter(void) +{ +} + +#endif /* !__ASSEMBLY__ */ + + +/* + * timestamp counter specifications + */ + +#define TMTSCBR_MAX 0xffffffff +#define TMTSCBC TM45BC + +#ifndef __ASSEMBLY__ + +static inline void startup_timestamp_counter(void) +{ + /* set up timer 4 & 5 cascaded as a 32-bit counter to count real time + * - count down from 4Gig-1 to 0 and wrap at IOCLK rate + */ + TM45BR = TMTSCBR_MAX; + + TM4MD = TM4MD_SRC_IOCLK; + TM4MD |= TM4MD_INIT_COUNTER; + TM4MD &= ~TM4MD_INIT_COUNTER; + TM4ICR = 0; + + TM5MD = TM5MD_SRC_TM4CASCADE; + TM5MD |= TM5MD_INIT_COUNTER; + TM5MD &= ~TM5MD_INIT_COUNTER; + TM5ICR = 0; + + TM5MD |= TM5MD_COUNT_ENABLE; + TM4MD |= TM4MD_COUNT_ENABLE; +} + +static inline void shutdown_timestamp_counter(void) +{ + TM4MD = 0; + TM5MD = 0; +} + +/* + * we use a cascaded pair of 16-bit down-counting timers to count I/O + * clock cycles for the purposes of time keeping + */ +typedef unsigned long cycles_t; + +static inline cycles_t read_timestamp_counter(void) +{ + return (cycles_t)TMTSCBC; +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_UNIT_TIMEX_H */ diff --git a/arch/mn10300/unit-asb2303/leds.c b/arch/mn10300/unit-asb2303/leds.c index cd4bc78..c038393 100644 --- a/arch/mn10300/unit-asb2303/leds.c +++ b/arch/mn10300/unit-asb2303/leds.c @@ -16,7 +16,7 @@ #include <asm/processor.h> #include <asm/intctl-regs.h> #include <asm/rtc-regs.h> -#include <asm/unit/leds.h> +#include <unit/leds.h> #if 0 static const u8 asb2303_led_hex_tbl[16] = { diff --git a/arch/mn10300/unit-asb2303/smc91111.c b/arch/mn10300/unit-asb2303/smc91111.c index 30875dd..43c2464 100644 --- a/arch/mn10300/unit-asb2303/smc91111.c +++ b/arch/mn10300/unit-asb2303/smc91111.c @@ -18,7 +18,7 @@ #include <asm/timex.h> #include <asm/processor.h> #include <asm/intctl-regs.h> -#include <asm/unit/smc91111.h> +#include <unit/smc91111.h> static struct resource smc91c111_resources[] = { [0] = { diff --git a/arch/mn10300/unit-asb2305/include/unit/clock.h b/arch/mn10300/unit-asb2305/include/unit/clock.h new file mode 100644 index 0000000..7d51484 --- /dev/null +++ b/arch/mn10300/unit-asb2305/include/unit/clock.h @@ -0,0 +1,45 @@ +/* ASB2305-specific clocks + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_UNIT_CLOCK_H +#define _ASM_UNIT_CLOCK_H + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_MN10300_RTC + +extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */ +extern unsigned long mn10300_iobclk; +extern unsigned long mn10300_tsc_per_HZ; + +#define MN10300_IOCLK ((unsigned long)mn10300_ioclk) +/* If this processors has a another clock, uncomment the below. */ +/* #define MN10300_IOBCLK ((unsigned long)mn10300_iobclk) */ + +#else /* !CONFIG_MN10300_RTC */ + +#define MN10300_IOCLK 33333333UL +/* #define MN10300_IOBCLK 66666666UL */ + +#endif /* !CONFIG_MN10300_RTC */ + +#define MN10300_JCCLK MN10300_IOCLK +#define MN10300_TSCCLK MN10300_IOCLK + +#ifdef CONFIG_MN10300_RTC +#define MN10300_TSC_PER_HZ ((unsigned long)mn10300_tsc_per_HZ) +#else /* !CONFIG_MN10300_RTC */ +#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ) +#endif /* !CONFIG_MN10300_RTC */ + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_UNIT_CLOCK_H */ diff --git a/arch/mn10300/unit-asb2305/include/unit/leds.h b/arch/mn10300/unit-asb2305/include/unit/leds.h new file mode 100644 index 0000000..bc471f6 --- /dev/null +++ b/arch/mn10300/unit-asb2305/include/unit/leds.h @@ -0,0 +1,51 @@ +/* ASB2305-specific LEDs + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_UNIT_LEDS_H +#define _ASM_UNIT_LEDS_H + +#include <asm/pio-regs.h> +#include <asm/cpu-regs.h> +#include <asm/exceptions.h> + +#define ASB2305_7SEGLEDS __SYSREG(0xA6F90000, u32) + +/* perform a hard reset by driving PIO06 low */ +#define mn10300_unit_hard_reset() \ +do { \ + P0OUT &= 0xbf; \ + P0MD = (P0MD & P0MD_6) | P0MD_6_OUT; \ +} while (0) + +/* + * use the 7-segment LEDs to indicate states + */ +/* indicate double-fault by displaying "db-f" on the LEDs */ +#define mn10300_set_dbfleds \ + mov 0x43077f1d,d0 ; \ + mov d0,(ASB2305_7SEGLEDS) + +/* flip the 7-segment LEDs between "Gdb-" and "----" */ +#define mn10300_set_gdbleds(ONOFF) \ +do { \ + ASB2305_7SEGLEDS = (ONOFF) ? 0x8543077f : 0x7f7f7f7f; \ +} while (0) + +#ifndef __ASSEMBLY__ +extern void peripheral_leds_display_exception(enum exception_code); +extern void peripheral_leds_led_chase(void); +extern void peripheral_leds7x4_display_dec(unsigned int, unsigned int); +extern void peripheral_leds7x4_display_hex(unsigned int, unsigned int); +extern void peripheral_leds7x4_display_minssecs(unsigned int, unsigned int); +extern void peripheral_leds7x4_display_rtc(void); +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_UNIT_LEDS_H */ diff --git a/arch/mn10300/unit-asb2305/include/unit/serial.h b/arch/mn10300/unit-asb2305/include/unit/serial.h new file mode 100644 index 0000000..3bfc9093 --- /dev/null +++ b/arch/mn10300/unit-asb2305/include/unit/serial.h @@ -0,0 +1,120 @@ +/* ASB2305-specific 8250 serial ports + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UNIT_SERIAL_H +#define _ASM_UNIT_SERIAL_H + +#include <asm/cpu/cpu-regs.h> +#include <proc/irq.h> +#include <linux/serial_reg.h> + +#define SERIAL_PORT0_BASE_ADDRESS 0xA6FB0000 +#define ASB2305_DEBUG_MCR __SYSREG(0xA6FB0000 + UART_MCR * 2, u8) + +#define SERIAL_IRQ XIRQ0 /* Dual serial (PC16552) (Hi) */ + +/* + * dispose of the /dev/ttyS0 serial port + */ +#ifndef CONFIG_GDBSTUB_ON_TTYSx + +#define SERIAL_PORT_DFNS \ + { \ + .baud_base = BASE_BAUD, \ + .irq = SERIAL_IRQ, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = (u8 *) SERIAL_PORT0_BASE_ADDRESS, \ + .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM, \ + }, + +#ifndef __ASSEMBLY__ + +static inline void __debug_to_serial(const char *p, int n) +{ +} + +#endif /* !__ASSEMBLY__ */ + +#else /* CONFIG_GDBSTUB_ON_TTYSx */ + +#define SERIAL_PORT_DFNS /* stolen by gdb-stub */ + +#if defined(CONFIG_GDBSTUB_ON_TTYS0) +#define GDBPORT_SERIAL_RX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX * 4, u8) +#define GDBPORT_SERIAL_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 4, u8) +#define GDBPORT_SERIAL_DLL __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 4, u8) +#define GDBPORT_SERIAL_DLM __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 4, u8) +#define GDBPORT_SERIAL_IER __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 4, u8) +#define GDBPORT_SERIAL_IIR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 4, u8) +#define GDBPORT_SERIAL_FCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 4, u8) +#define GDBPORT_SERIAL_LCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 4, u8) +#define GDBPORT_SERIAL_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8) +#define GDBPORT_SERIAL_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8) +#define GDBPORT_SERIAL_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8) +#define GDBPORT_SERIAL_SCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 4, u8) +#define GDBPORT_SERIAL_IRQ SERIAL_IRQ + +#elif defined(CONFIG_GDBSTUB_ON_TTYS1) +#error The ASB2305 doesnt have a /dev/ttyS1 +#endif + +#ifndef __ASSEMBLY__ + +#define TTYS0_TX __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX * 4, u8) +#define TTYS0_MCR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 4, u8) +#define TTYS0_LSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 4, u8) +#define TTYS0_MSR __SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 4, u8) + +#define LSR_WAIT_FOR(STATE) \ +do { \ + while (!(TTYS0_LSR & UART_LSR_##STATE)) {} \ +} while (0) +#define FLOWCTL_WAIT_FOR(LINE) \ +do { \ + while (!(TTYS0_MSR & UART_MSR_##LINE)) {} \ +} while (0) +#define FLOWCTL_CLEAR(LINE) \ +do { \ + TTYS0_MCR &= ~UART_MCR_##LINE; \ +} while (0) +#define FLOWCTL_SET(LINE) \ +do { \ + TTYS0_MCR |= UART_MCR_##LINE; \ +} while (0) +#define FLOWCTL_QUERY(LINE) ({ TTYS0_MSR & UART_MSR_##LINE; }) + +static inline void __debug_to_serial(const char *p, int n) +{ + char ch; + + FLOWCTL_SET(DTR); + + for (; n > 0; n--) { + LSR_WAIT_FOR(THRE); + FLOWCTL_WAIT_FOR(CTS); + + ch = *p++; + if (ch == 0x0a) { + TTYS0_TX = 0x0d; + LSR_WAIT_FOR(THRE); + FLOWCTL_WAIT_FOR(CTS); + } + TTYS0_TX = ch; + } + + FLOWCTL_CLEAR(DTR); +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* CONFIG_GDBSTUB_ON_TTYSx */ + +#endif /* _ASM_UNIT_SERIAL_H */ diff --git a/arch/mn10300/unit-asb2305/include/unit/timex.h b/arch/mn10300/unit-asb2305/include/unit/timex.h new file mode 100644 index 0000000..a71c49a --- /dev/null +++ b/arch/mn10300/unit-asb2305/include/unit/timex.h @@ -0,0 +1,135 @@ +/* ASB2305 timer specifcations + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#ifndef _ASM_UNIT_TIMEX_H +#define _ASM_UNIT_TIMEX_H + +#ifndef __ASSEMBLY__ +#include <linux/irq.h> +#endif /* __ASSEMBLY__ */ + +#include <asm/cpu/timer-regs.h> +#include <unit/clock.h> + +/* + * jiffies counter specifications + */ + +#define TMJCBR_MAX 0xffff +#define TMJCBC TM01BC + +#define TMJCMD TM01MD +#define TMJCBR TM01BR +#define TMJCIRQ TM1IRQ +#define TMJCICR TM1ICR +#define TMJCICR_LEVEL GxICR_LEVEL_5 + +#ifndef __ASSEMBLY__ + +static inline void startup_jiffies_counter(void) +{ + unsigned rate; + u16 md, t16; + + /* use as little prescaling as possible to avoid losing accuracy */ + md = TM0MD_SRC_IOCLK; + rate = MN10300_JCCLK / HZ; + + if (rate > TMJCBR_MAX) { + md = TM0MD_SRC_IOCLK_8; + rate = MN10300_JCCLK / 8 / HZ; + + if (rate > TMJCBR_MAX) { + md = TM0MD_SRC_IOCLK_32; + rate = MN10300_JCCLK / 32 / HZ; + + if (rate > TMJCBR_MAX) + BUG(); + } + } + + TMJCBR = rate - 1; + t16 = TMJCBR; + + TMJCMD = + md | + TM1MD_SRC_TM0CASCADE << 8 | + TM0MD_INIT_COUNTER | + TM1MD_INIT_COUNTER << 8; + + TMJCMD = + md | + TM1MD_SRC_TM0CASCADE << 8 | + TM0MD_COUNT_ENABLE | + TM1MD_COUNT_ENABLE << 8; + + t16 = TMJCMD; + + TMJCICR |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST; + t16 = TMJCICR; +} + +static inline void shutdown_jiffies_counter(void) +{ +} + +#endif /* !__ASSEMBLY__ */ + + +/* + * timestamp counter specifications + */ + +#define TMTSCBR_MAX 0xffffffff +#define TMTSCBC TM45BC + +#ifndef __ASSEMBLY__ + +static inline void startup_timestamp_counter(void) +{ + /* set up timer 4 & 5 cascaded as a 32-bit counter to count real time + * - count down from 4Gig-1 to 0 and wrap at IOCLK rate + */ + TM45BR = TMTSCBR_MAX; + + TM4MD = TM4MD_SRC_IOCLK; + TM4MD |= TM4MD_INIT_COUNTER; + TM4MD &= ~TM4MD_INIT_COUNTER; + TM4ICR = 0; + + TM5MD = TM5MD_SRC_TM4CASCADE; + TM5MD |= TM5MD_INIT_COUNTER; + TM5MD &= ~TM5MD_INIT_COUNTER; + TM5ICR = 0; + + TM5MD |= TM5MD_COUNT_ENABLE; + TM4MD |= TM4MD_COUNT_ENABLE; +} + +static inline void shutdown_timestamp_counter(void) +{ + TM4MD = 0; + TM5MD = 0; +} + +/* + * we use a cascaded pair of 16-bit down-counting timers to count I/O + * clock cycles for the purposes of time keeping + */ +typedef unsigned long cycles_t; + +static inline cycles_t read_timestamp_counter(void) +{ + return (cycles_t) TMTSCBC; +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_UNIT_TIMEX_H */ diff --git a/arch/mn10300/unit-asb2305/leds.c b/arch/mn10300/unit-asb2305/leds.c index e99dcc9..d345ff9 100644 --- a/arch/mn10300/unit-asb2305/leds.c +++ b/arch/mn10300/unit-asb2305/leds.c @@ -15,7 +15,7 @@ #include <asm/processor.h> #include <asm/cpu/intctl-regs.h> #include <asm/cpu/rtc-regs.h> -#include <asm/unit/leds.h> +#include <unit/leds.h> static const u8 asb2305_led_hex_tbl[16] = { 0x80, 0xf2, 0x48, 0x60, 0x32, 0x24, 0x04, 0xf0, diff --git a/arch/mn10300/unit-asb2305/unit-init.c b/arch/mn10300/unit-asb2305/unit-init.c index 72812a9..1c452cc 100644 --- a/arch/mn10300/unit-asb2305/unit-init.c +++ b/arch/mn10300/unit-asb2305/unit-init.c @@ -18,7 +18,7 @@ #include <asm/cpu/intctl-regs.h> #include <asm/cpu/rtc-regs.h> #include <asm/cpu/serial-regs.h> -#include <asm/unit/serial.h> +#include <unit/serial.h> /* * initialise some of the unit hardware before gdbstub is set up diff --git a/arch/powerpc/include/asm/parport.h b/arch/powerpc/include/asm/parport.h index 414c50e..94942d6 100644 --- a/arch/powerpc/include/asm/parport.h +++ b/arch/powerpc/include/asm/parport.h @@ -29,7 +29,7 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) prop = of_get_property(np, "interrupts", NULL); if (!prop) continue; - if (parport_pc_probe_port(io1, io2, prop[0], autodma, NULL) != NULL) + if (parport_pc_probe_port(io1, io2, prop[0], autodma, NULL, 0) != NULL) count++; } return count; diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index dcb667c..2eca5fe 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -82,6 +82,7 @@ config S390 select USE_GENERIC_SMP_HELPERS if SMP select HAVE_SYSCALL_WRAPPERS select HAVE_FUNCTION_TRACER + select HAVE_DEFAULT_NO_SPIN_MUTEXES select HAVE_OPROFILE select HAVE_KPROBES select HAVE_KRETPROBES diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5e4babe..e7390dd 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -14,6 +14,7 @@ config SUPERH select HAVE_GENERIC_DMA_COHERENT select HAVE_IOREMAP_PROT if MMU select HAVE_ARCH_TRACEHOOK + select HAVE_DMA_API_DEBUG help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast @@ -21,7 +22,7 @@ config SUPERH <http://www.linux-sh.org/>. config SUPERH32 - def_bool !SUPERH64 + def_bool ARCH = "sh" select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_FUNCTION_TRACER @@ -31,7 +32,7 @@ config SUPERH32 select ARCH_HIBERNATION_POSSIBLE if MMU config SUPERH64 - def_bool y if CPU_SH5 + def_bool ARCH = "sh64" config ARCH_DEFCONFIG string @@ -187,6 +188,8 @@ config ARCH_SHMOBILE bool select ARCH_SUSPEND_POSSIBLE +if SUPERH32 + choice prompt "Processor sub-type selection" @@ -408,6 +411,15 @@ config CPU_SUBTYPE_SH7366 select SYS_SUPPORTS_NUMA select SYS_SUPPORTS_CMT +endchoice + +endif + +if SUPERH64 + +choice + prompt "Processor sub-type selection" + # SH-5 Processor Support config CPU_SUBTYPE_SH5_101 @@ -420,6 +432,8 @@ config CPU_SUBTYPE_SH5_103 endchoice +endif + source "arch/sh/mm/Kconfig" source "arch/sh/Kconfig.cpu" diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index 912458f..39e4691 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c @@ -349,6 +349,7 @@ static int ov7725_power(struct device *dev, int mode) static struct ov772x_camera_info ov7725_info = { .buswidth = SOCAM_DATAWIDTH_8, .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, + .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), .link = { .power = ov7725_power, }, diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c index 8367d1d..beb88c4 100644 --- a/arch/sh/boards/board-urquell.c +++ b/arch/sh/boards/board-urquell.c @@ -2,6 +2,8 @@ * Renesas Technology Corp. SH7786 Urquell Support. * * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com> + * + * Based on board-sh7785lcr.c * Copyright (C) 2008 Yoshihiro Shimoda * * This file is subject to the terms and conditions of the GNU General Public @@ -21,6 +23,32 @@ #include <asm/heartbeat.h> #include <asm/sizes.h> +/* + * bit 1234 5678 + *---------------------------- + * SW1 0101 0010 -> Pck 33MHz version + * (1101 0010) Pck 66MHz version + * SW2 0x1x xxxx -> little endian + * 29bit mode + * SW47 0001 1000 -> CS0 : on-board flash + * CS1 : SRAM, registers, LAN, PCMCIA + * 38400 bps for SCIF1 + * + * Address + * 0x00000000 - 0x04000000 (CS0) Nor Flash + * 0x04000000 - 0x04200000 (CS1) SRAM + * 0x05000000 - 0x05800000 (CS1) on board register + * 0x05800000 - 0x06000000 (CS1) LAN91C111 + * 0x06000000 - 0x06400000 (CS1) PCMCIA + * 0x08000000 - 0x10000000 (CS2-CS3) DDR3 + * 0x10000000 - 0x14000000 (CS4) PCIe + * 0x14000000 - 0x14800000 (CS5) Core0 LRAM/URAM + * 0x14800000 - 0x15000000 (CS5) Core1 LRAM/URAM + * 0x18000000 - 0x1C000000 (CS6) ATA/NAND-Flash + * 0x1C000000 - (CS7) SH7786 Control register + */ + +/* HeartBeat */ static struct resource heartbeat_resources[] = { [0] = { .start = BOARDREG(SLEDR), @@ -43,6 +71,7 @@ static struct platform_device heartbeat_device = { .resource = heartbeat_resources, }; +/* LAN91C111 */ static struct smc91x_platdata smc91x_info = { .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, }; @@ -69,6 +98,7 @@ static struct platform_device smc91x_eth_device = { }, }; +/* Nor Flash */ static struct mtd_partition nor_flash_partitions[] = { { .name = "loader", diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c index e8b7446..fb0869f 100644 --- a/arch/sh/drivers/pci/ops-sh7785lcr.c +++ b/arch/sh/drivers/pci/ops-sh7785lcr.c @@ -48,8 +48,13 @@ EXPORT_SYMBOL(board_pci_channels); static struct sh4_pci_address_map sh7785_pci_map = { .window0 = { +#if defined(CONFIG_32BIT) + .base = SH7780_32BIT_DDR_BASE_ADDR, + .size = 0x40000000, +#else .base = SH7780_CS0_BASE_ADDR, .size = 0x20000000, +#endif }, .flags = SH4_PCIC_NO_RESET, diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 97b2c98..93adc71 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -104,6 +104,8 @@ #define SH7780_CS5_BASE_ADDR (SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE) #define SH7780_CS6_BASE_ADDR (SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE) +#define SH7780_32BIT_DDR_BASE_ADDR 0x40000000 + struct sh4_pci_address_map; /* arch/sh/drivers/pci/pci-sh7780.c */ diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index e36c7b8..0d6ac7a 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/pci.h> #include <linux/init.h> +#include <linux/dma-debug.h> #include <asm/io.h> static int __init pcibios_init(void) @@ -43,6 +44,8 @@ static int __init pcibios_init(void) pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); + dma_debug_add_bus(&pci_bus_type); + return 0; } subsys_initcall(pcibios_init); diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index 627315e..ea9d4f4 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h @@ -3,6 +3,7 @@ #include <linux/mm.h> #include <linux/scatterlist.h> +#include <linux/dma-debug.h> #include <asm/cacheflush.h> #include <asm/io.h> #include <asm-generic/dma-coherent.h> @@ -38,16 +39,26 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction dir) { + dma_addr_t addr = virt_to_phys(ptr); + #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) if (dev->bus == &pci_bus_type) - return virt_to_phys(ptr); + return addr; #endif dma_cache_sync(dev, ptr, size, dir); - return virt_to_phys(ptr); + debug_dma_map_page(dev, virt_to_page(ptr), + (unsigned long)ptr & ~PAGE_MASK, size, + dir, addr, true); + + return addr; } -#define dma_unmap_single(dev, addr, size, dir) do { } while (0) +static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, + size_t size, enum dma_data_direction dir) +{ + debug_dma_unmap_page(dev, addr, size, dir, true); +} static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) @@ -59,12 +70,19 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir); #endif sg[i].dma_address = sg_phys(&sg[i]); + sg[i].dma_length = sg[i].length; } + debug_dma_map_sg(dev, sg, nents, i, dir); + return nents; } -#define dma_unmap_sg(dev, sg, nents, dir) do { } while (0) +static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ + debug_dma_unmap_sg(dev, sg, nents, dir); +} static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, @@ -111,6 +129,7 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir); #endif sg[i].dma_address = sg_phys(&sg[i]); + sg[i].dma_length = sg[i].length; } } @@ -119,6 +138,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev, enum dma_data_direction dir) { dma_sync_single(dev, dma_handle, size, dir); + debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir); } static inline void dma_sync_single_for_device(struct device *dev, @@ -127,6 +147,7 @@ static inline void dma_sync_single_for_device(struct device *dev, enum dma_data_direction dir) { dma_sync_single(dev, dma_handle, size, dir); + debug_dma_sync_single_for_device(dev, dma_handle, size, dir); } static inline void dma_sync_single_range_for_cpu(struct device *dev, @@ -136,6 +157,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, enum dma_data_direction direction) { dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction); + debug_dma_sync_single_range_for_cpu(dev, dma_handle, + offset, size, direction); } static inline void dma_sync_single_range_for_device(struct device *dev, @@ -145,6 +168,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev, enum dma_data_direction direction) { dma_sync_single_for_device(dev, dma_handle+offset, size, direction); + debug_dma_sync_single_range_for_device(dev, dma_handle, + offset, size, direction); } @@ -153,6 +178,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, enum dma_data_direction dir) { dma_sync_sg(dev, sg, nelems, dir); + debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir); } static inline void dma_sync_sg_for_device(struct device *dev, @@ -160,9 +186,9 @@ static inline void dma_sync_sg_for_device(struct device *dev, enum dma_data_direction dir) { dma_sync_sg(dev, sg, nelems, dir); + debug_dma_sync_sg_for_device(dev, sg, nelems, dir); } - static inline int dma_get_cache_alignment(void) { /* diff --git a/arch/sh/include/asm/scatterlist.h b/arch/sh/include/asm/scatterlist.h index 2084d03..c693d26 100644 --- a/arch/sh/include/asm/scatterlist.h +++ b/arch/sh/include/asm/scatterlist.h @@ -5,12 +5,13 @@ struct scatterlist { #ifdef CONFIG_DEBUG_SG - unsigned long sg_magic; + unsigned long sg_magic; #endif - unsigned long page_link; - unsigned int offset;/* for highmem, page offset */ - dma_addr_t dma_address; - unsigned int length; + unsigned long page_link; + unsigned int offset; /* for highmem, page offset */ + unsigned int length; + dma_addr_t dma_address; + unsigned int dma_length; }; #define ISA_DMA_THRESHOLD PHYS_ADDR_MASK diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h index a3f2395..8489a09 100644 --- a/arch/sh/include/asm/topology.h +++ b/arch/sh/include/asm/topology.h @@ -37,8 +37,11 @@ #define pcibus_to_node(bus) ((void)(bus), -1) #define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \ CPU_MASK_ALL : \ - node_to_cpumask(pcibus_to_node(bus)) \ - ) + node_to_cpumask(pcibus_to_node(bus))) +#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \ + CPU_MASK_ALL_PTR : \ + cpumask_of_node(pcibus_to_node(bus))) + #endif #include <asm-generic/topology.h> diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index d52c000..2efb819 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h @@ -341,8 +341,10 @@ #define __NR_dup3 330 #define __NR_pipe2 331 #define __NR_inotify_init1 332 +#define __NR_preadv 333 +#define __NR_pwritev 334 -#define NR_syscalls 333 +#define NR_syscalls 335 #ifdef __KERNEL__ diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h index 7c54e91..6eb9d29 100644 --- a/arch/sh/include/asm/unistd_64.h +++ b/arch/sh/include/asm/unistd_64.h @@ -381,10 +381,12 @@ #define __NR_dup3 358 #define __NR_pipe2 359 #define __NR_inotify_init1 360 +#define __NR_preadv 361 +#define __NR_pwritev 362 #ifdef __KERNEL__ -#define NR_syscalls 361 +#define NR_syscalls 363 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 5a47e1c..90e8cff 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -143,14 +143,14 @@ static void __init sh7786_usb_setup(void) * Set the PHY and PLL enable bit */ __raw_writel(PHY_ENB | PLL_ENB, USBPCTL1); - while (i-- && - ((__raw_readl(USBST) & ACT_PLL_STATUS) != ACT_PLL_STATUS)) + while (i--) { + if (ACT_PLL_STATUS == (__raw_readl(USBST) & ACT_PLL_STATUS)) { + /* Set the PHY RST bit */ + __raw_writel(PHY_ENB | PLL_ENB | PHY_RST, USBPCTL1); + printk(KERN_INFO "sh7786 usb setup done\n"); + break; + } cpu_relax(); - - if (i) { - /* Set the PHY RST bit */ - __raw_writel(PHY_ENB | PLL_ENB | PHY_RST, USBPCTL1); - printk(KERN_INFO "sh7786 usb setup done\n"); } } diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index e67c173..05202ed 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S @@ -349,3 +349,5 @@ ENTRY(sys_call_table) .long sys_dup3 /* 330 */ .long sys_pipe2 .long sys_inotify_init1 + .long sys_preadv + .long sys_writev diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index 557cb91..a083609 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S @@ -387,3 +387,5 @@ sys_call_table: .long sys_dup3 .long sys_pipe2 .long sys_inotify_init1 /* 360 */ + .long sys_preadv + .long sys_pwritev diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index edcd5fb..e098ec1 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -10,11 +10,22 @@ * for more details. */ #include <linux/mm.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/dma-debug.h> +#include <linux/io.h> #include <asm/cacheflush.h> #include <asm/addrspace.h> -#include <asm/io.h> + +#define PREALLOC_DMA_DEBUG_ENTRIES 4096 + +static int __init dma_init(void) +{ + dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); + return 0; +} +fs_initcall(dma_init); void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) @@ -45,6 +56,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size, split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order); *dma_handle = virt_to_phys(ret); + + debug_dma_alloc_coherent(dev, size, *dma_handle, ret_nocache); + return ret_nocache; } EXPORT_SYMBOL(dma_alloc_coherent); @@ -56,12 +70,15 @@ void dma_free_coherent(struct device *dev, size_t size, unsigned long pfn = dma_handle >> PAGE_SHIFT; int k; - if (!dma_release_from_coherent(dev, order, vaddr)) { - WARN_ON(irqs_disabled()); /* for portability */ - for (k = 0; k < (1 << order); k++) - __free_pages(pfn_to_page(pfn + k), 0); - iounmap(vaddr); - } + WARN_ON(irqs_disabled()); /* for portability */ + + if (dma_release_from_coherent(dev, order, vaddr)) + return; + + debug_dma_free_coherent(dev, size, vaddr, dma_handle); + for (k = 0; k < (1 << order); k++) + __free_pages(pfn_to_page(pfn + k), 0); + iounmap(vaddr); } EXPORT_SYMBOL(dma_free_coherent); diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index dff3f02..ff9ead6 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -117,7 +117,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id if (!strcmp(parent->name, "dma")) { p = parport_pc_probe_port(base, base + 0x400, op->irqs[0], PARPORT_DMA_NOFIFO, - op->dev.parent->parent); + op->dev.parent->parent, 0); if (!p) return -ENOMEM; dev_set_drvdata(&op->dev, p); @@ -168,7 +168,8 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id p = parport_pc_probe_port(base, base + 0x400, op->irqs[0], slot, - op->dev.parent); + op->dev.parent, + 0); err = -ENOMEM; if (!p) goto out_disable_irq; diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index 031f038..b8eb71e 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h @@ -392,8 +392,10 @@ #define __NR_pipe2 321 #define __NR_inotify_init1 322 #define __NR_accept4 323 +#define __NR_preadv 324 +#define __NR_pwritev 325 -#define NR_SYSCALLS 324 +#define NR_SYSCALLS 326 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index b4a12c9..27381f1 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -99,8 +99,7 @@ static inline u64 of_read_addr(const u32 *cell, int size) return r; } -static void __init get_cells(struct device_node *dp, - int *addrc, int *sizec) +static void get_cells(struct device_node *dp, int *addrc, int *sizec) { if (addrc) *addrc = of_n_addr_cells(dp); diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 9462b68..d53f45b 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -409,8 +409,8 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm) upa_writeq(~(u64)0, pbm->pbm_regs + FIRE_PEC_IENAB); } -static int __init pci_fire_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op, u32 portid) +static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, + struct of_device *op, u32 portid) { const struct linux_prom64_registers *regs; struct device_node *dp = op->node; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 3b34344..142b9d6 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -365,8 +365,8 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void __init psycho_scan_bus(struct pci_pbm_info *pbm, - struct device *parent) +static void __devinit psycho_scan_bus(struct pci_pbm_info *pbm, + struct device *parent) { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = 0; @@ -482,8 +482,8 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, #define PSYCHO_MEMSPACE_B 0x180000000UL #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL -static void __init psycho_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op, int is_pbm_a) +static void __devinit psycho_pbm_init(struct pci_pbm_info *pbm, + struct of_device *op, int is_pbm_a) { psycho_pbm_init_common(pbm, op, "PSYCHO", PBM_CHIP_TYPE_PSYCHO); psycho_pbm_strbuf_init(pbm, is_pbm_a); diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 713257b..ba6fbeb 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -402,8 +402,8 @@ static void apb_init(struct pci_bus *sabre_bus) } } -static void __init sabre_scan_bus(struct pci_pbm_info *pbm, - struct device *parent) +static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm, + struct device *parent) { static int once; @@ -442,8 +442,8 @@ static void __init sabre_scan_bus(struct pci_pbm_info *pbm, sabre_register_error_handlers(pbm); } -static void __init sabre_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op) +static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, + struct of_device *op) { psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE); pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 0ef0ab3..5db5ebe 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -545,8 +545,8 @@ static const struct dma_ops sun4v_dma_ops = { .sync_sg_for_cpu = dma_4v_sync_sg_for_cpu, }; -static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm, - struct device *parent) +static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, + struct device *parent) { struct property *prop; struct device_node *dp; @@ -559,8 +559,8 @@ static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm, /* XXX register error interrupt handlers XXX */ } -static unsigned long __init probe_existing_entries(struct pci_pbm_info *pbm, - struct iommu *iommu) +static unsigned long __devinit probe_existing_entries(struct pci_pbm_info *pbm, + struct iommu *iommu) { struct iommu_arena *arena = &iommu->arena; unsigned long i, cnt = 0; @@ -587,7 +587,7 @@ static unsigned long __init probe_existing_entries(struct pci_pbm_info *pbm, return cnt; } -static int __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm) +static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm) { static const u32 vdma_default[] = { 0x80000000, 0x80000000 }; struct iommu *iommu = pbm->iommu; @@ -889,8 +889,8 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) } #endif /* !(CONFIG_PCI_MSI) */ -static int __init pci_sun4v_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op, u32 devhandle) +static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, + struct of_device *op, u32 devhandle) { struct device_node *dp = op->node; int err; diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index ae88f06..e2a045c 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -23,7 +23,7 @@ static irqreturn_t power_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) +static int __devinit has_button_interrupt(unsigned int irq, struct device_node *dp) { if (irq == 0xffffffff) return 0; diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index dccc95d..00ec3b1 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -81,4 +81,4 @@ sys_call_table: /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 -/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4 +/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv, sys_pwritev diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index a8000b1..82b5bf8 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -82,7 +82,7 @@ sys_call_table32: .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 -/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4 +/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv, compat_sys_pwritev #endif /* CONFIG_COMPAT */ @@ -156,4 +156,4 @@ sys_call_table: .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 -/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4 +/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv, sys_pwritev diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 2c8dfeb..f26a352 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -70,8 +70,8 @@ extern struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES]; #define MAX_BANKS 32 -static struct linux_prom64_registers pavail[MAX_BANKS] __initdata; -static int pavail_ents __initdata; +static struct linux_prom64_registers pavail[MAX_BANKS] __devinitdata; +static int pavail_ents __devinitdata; static int cmp_p64(const void *a, const void *b) { @@ -968,7 +968,7 @@ int of_node_to_nid(struct device_node *dp) return nid; } -static void add_node_ranges(void) +static void __init add_node_ranges(void) { int i; @@ -1841,7 +1841,7 @@ void __init paging_init(void) printk("Booting Linux...\n"); } -int __init page_in_phys_avail(unsigned long paddr) +int __devinit page_in_phys_avail(unsigned long paddr) { int i; diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4b34082..bc25b9f 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -252,17 +252,13 @@ config SMP config X86_X2APIC bool "Support x2apic" - depends on X86_LOCAL_APIC && X86_64 - select INTR_REMAP + depends on X86_LOCAL_APIC && X86_64 && INTR_REMAP ---help--- This enables x2apic support on CPUs that have this feature. This allows 32-bit apic IDs (so it can support very large systems), and accesses the local apic via MSRs not via mmio. - ( On certain CPU models you may need to enable INTR_REMAP too, - to get functional x2apic mode. ) - If you don't know what to do here, say N. config SPARSE_IRQ diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c index 95d86ce..9e0587a 100644 --- a/arch/x86/boot/video-vga.c +++ b/arch/x86/boot/video-vga.c @@ -129,22 +129,18 @@ u16 vga_crtc(void) return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4; } -static void vga_set_480_scanlines(int lines) +static void vga_set_480_scanlines(void) { u16 crtc; /* CRTC base address */ u8 csel; /* CRTC miscellaneous output register */ - u8 ovfw; /* CRTC overflow register */ - int end = lines-1; crtc = vga_crtc(); - ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40); - out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */ out_idx(0x0b, crtc, 0x06); /* Vertical total */ - out_idx(ovfw, crtc, 0x07); /* Vertical overflow */ + out_idx(0x3e, crtc, 0x07); /* Vertical overflow */ out_idx(0xea, crtc, 0x10); /* Vertical sync start */ - out_idx(end, crtc, 0x12); /* Vertical display end */ + out_idx(0xdf, crtc, 0x12); /* Vertical display end */ out_idx(0xe7, crtc, 0x15); /* Vertical blank start */ out_idx(0x04, crtc, 0x16); /* Vertical blank end */ csel = inb(0x3cc); @@ -153,21 +149,38 @@ static void vga_set_480_scanlines(int lines) outb(csel, 0x3c2); } +static void vga_set_vertical_end(int lines) +{ + u16 crtc; /* CRTC base address */ + u8 ovfw; /* CRTC overflow register */ + int end = lines-1; + + crtc = vga_crtc(); + + ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40); + + out_idx(ovfw, crtc, 0x07); /* Vertical overflow */ + out_idx(end, crtc, 0x12); /* Vertical display end */ +} + static void vga_set_80x30(void) { - vga_set_480_scanlines(30*16); + vga_set_480_scanlines(); + vga_set_vertical_end(30*16); } static void vga_set_80x34(void) { + vga_set_480_scanlines(); vga_set_14font(); - vga_set_480_scanlines(34*14); + vga_set_vertical_end(34*14); } static void vga_set_80x60(void) { + vga_set_480_scanlines(); vga_set_8font(); - vga_set_480_scanlines(60*8); + vga_set_vertical_end(60*8); } static int vga_set_mode(struct mode_info *mode) diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h index 2228020..2228020 100755..100644 --- a/arch/x86/include/asm/cpu_debug.h +++ b/arch/x86/include/asm/cpu_debug.h diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 0beba0d..bb83b1c 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -154,6 +154,7 @@ * CPUID levels like 0x6, 0xA etc */ #define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */ +#define X86_FEATURE_ARAT (7*32+ 1) /* Always Running APIC Timer */ /* Virtualization flags: Linux defined */ #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 81937a5..2d81af3 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -151,11 +151,11 @@ extern pte_t *pkmap_page_table; void __native_set_fixmap(enum fixed_addresses idx, pte_t pte); void native_set_fixmap(enum fixed_addresses idx, - unsigned long phys, pgprot_t flags); + phys_addr_t phys, pgprot_t flags); #ifndef CONFIG_PARAVIRT static inline void __set_fixmap(enum fixed_addresses idx, - unsigned long phys, pgprot_t flags) + phys_addr_t phys, pgprot_t flags) { native_set_fixmap(idx, phys, flags); } diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index e5383e3..7373932 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -193,8 +193,10 @@ extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size); */ extern void early_ioremap_init(void); extern void early_ioremap_reset(void); -extern void __iomem *early_ioremap(unsigned long offset, unsigned long size); -extern void __iomem *early_memremap(unsigned long offset, unsigned long size); +extern void __iomem *early_ioremap(resource_size_t phys_addr, + unsigned long size); +extern void __iomem *early_memremap(resource_size_t phys_addr, + unsigned long size); extern void early_iounmap(void __iomem *addr, unsigned long size); #define IO_SPACE_LIMIT 0xffff diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 7727aa8..378e369 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -347,7 +347,7 @@ struct pv_mmu_ops { /* Sometimes the physical address is a pfn, and sometimes its an mfn. We can tell which is which from the index. */ void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx, - unsigned long phys, pgprot_t flags); + phys_addr_t phys, pgprot_t flags); }; struct raw_spinlock; @@ -1432,7 +1432,7 @@ static inline void arch_leave_lazy_mmu_mode(void) void arch_flush_lazy_mmu_mode(void); static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, - unsigned long phys, pgprot_t flags) + phys_addr_t phys, pgprot_t flags) { pv_mmu_ops.set_fixmap(idx, phys, flags); } diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 34c5237..fcf4d92 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -352,6 +352,11 @@ struct i387_soft_struct { u32 entry_eip; }; +struct ymmh_struct { + /* 16 * 16 bytes for each YMMH-reg = 256 bytes */ + u32 ymmh_space[64]; +}; + struct xsave_hdr_struct { u64 xstate_bv; u64 reserved1[2]; @@ -361,6 +366,7 @@ struct xsave_hdr_struct { struct xsave_struct { struct i387_fxsave_struct i387; struct xsave_hdr_struct xsave_hdr; + struct ymmh_struct ymmh; /* new processor state extensions will go here */ } __attribute__ ((packed, aligned (64))); diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h index d5cd6c5..a4737dd 100644 --- a/arch/x86/include/asm/required-features.h +++ b/arch/x86/include/asm/required-features.h @@ -50,7 +50,7 @@ #ifdef CONFIG_X86_64 #define NEED_PSE 0 #define NEED_MSR (1<<(X86_FEATURE_MSR & 31)) -#define NEED_PGE (1<<(X86_FEATURE_PGE & 31)) +#define NEED_PGE 0 #define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31)) #define NEED_XMM (1<<(X86_FEATURE_XMM & 31)) #define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31)) diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h index ec66649..72e5a44 100644 --- a/arch/x86/include/asm/sigcontext.h +++ b/arch/x86/include/asm/sigcontext.h @@ -269,6 +269,11 @@ struct _xsave_hdr { __u64 reserved2[5]; }; +struct _ymmh_state { + /* 16 * 16 bytes for each YMMH-reg */ + __u32 ymmh_space[64]; +}; + /* * Extended state pointed by the fpstate pointer in the sigcontext. * In addition to the fpstate, information encoded in the xstate_hdr @@ -278,6 +283,7 @@ struct _xsave_hdr { struct _xstate { struct _fpstate fpstate; struct _xsave_hdr xstate_hdr; + struct _ymmh_state ymmh; /* new processor state extensions go here */ }; diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 1a918dd..018a0a4 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -124,7 +124,8 @@ static inline unsigned long mfn_to_local_pfn(unsigned long mfn) /* VIRT <-> MACHINE conversion */ #define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v)))) -#define virt_to_mfn(v) (pfn_to_mfn(PFN_DOWN(__pa(v)))) +#define virt_to_pfn(v) (PFN_DOWN(__pa(v))) +#define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v))) #define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) static inline unsigned long pte_mfn(pte_t pte) diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 08e9a1a..727acc1 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h @@ -7,6 +7,7 @@ #define XSTATE_FP 0x1 #define XSTATE_SSE 0x2 +#define XSTATE_YMM 0x4 #define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE) @@ -15,7 +16,7 @@ /* * These are the features that the OS can handle currently. */ -#define XCNTXT_MASK (XSTATE_FP | XSTATE_SSE) +#define XCNTXT_MASK (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) #ifdef CONFIG_X86_64 #define REX_PREFIX "0x48, " diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 098ec84..f287092 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -431,6 +431,12 @@ static void __cpuinit setup_APIC_timer(void) { struct clock_event_device *levt = &__get_cpu_var(lapic_events); + if (cpu_has(¤t_cpu_data, X86_FEATURE_ARAT)) { + lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP; + /* Make LAPIC timer preferrable over percpu HPET */ + lapic_clockevent.rating = 150; + } + memcpy(levt, &lapic_clockevent, sizeof(*levt)); levt->cpumask = cpumask_of(smp_processor_id()); diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 0014714..306e5e8 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -212,7 +212,7 @@ struct apic apic_flat = { .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = NULL, + .inquire_remote_apic = default_inquire_remote_apic, .read = native_apic_mem_read, .write = native_apic_mem_write, @@ -362,7 +362,7 @@ struct apic apic_physflat = { .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = NULL, + .inquire_remote_apic = default_inquire_remote_apic, .read = native_apic_mem_read, .write = native_apic_mem_write, diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 767fe7e..a2789e4 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2524,7 +2524,6 @@ static void irq_complete_move(struct irq_desc **descp) static inline void irq_complete_move(struct irq_desc **descp) {} #endif -#ifdef CONFIG_X86_X2APIC static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) { int apic, pin; @@ -2558,6 +2557,7 @@ eoi_ioapic_irq(struct irq_desc *desc) spin_unlock_irqrestore(&ioapic_lock, flags); } +#ifdef CONFIG_X86_X2APIC static void ack_x2apic_level(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); @@ -2634,6 +2634,9 @@ static void ack_apic_level(unsigned int irq) */ ack_APIC_irq(); + if (irq_remapped(irq)) + eoi_ioapic_irq(desc); + /* Now we can move and renable the irq */ if (unlikely(do_unmask_irq)) { /* Only migrate the irq if the ack has been received. diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index 8220ae6..c965e52 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c @@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, + { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 }, { 0, 0, 0, 0 } }; diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c index 46e29ab..46e29ab 100755..100644 --- a/arch/x86/kernel/cpu/cpu_debug.c +++ b/arch/x86/kernel/cpu/cpu_debug.c diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 19f6b9d..837c2c4 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -68,6 +68,7 @@ struct acpi_cpufreq_data { unsigned int max_freq; unsigned int resume; unsigned int cpu_feature; + u64 saved_aperf, saved_mperf; }; static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); @@ -152,7 +153,8 @@ struct drv_cmd { u32 val; }; -static long do_drv_read(void *_cmd) +/* Called via smp_call_function_single(), on the target CPU */ +static void do_drv_read(void *_cmd) { struct drv_cmd *cmd = _cmd; u32 h; @@ -169,10 +171,10 @@ static long do_drv_read(void *_cmd) default: break; } - return 0; } -static long do_drv_write(void *_cmd) +/* Called via smp_call_function_many(), on the target CPUs */ +static void do_drv_write(void *_cmd) { struct drv_cmd *cmd = _cmd; u32 lo, hi; @@ -191,23 +193,18 @@ static long do_drv_write(void *_cmd) default: break; } - return 0; } static void drv_read(struct drv_cmd *cmd) { cmd->val = 0; - work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd); + smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1); } static void drv_write(struct drv_cmd *cmd) { - unsigned int i; - - for_each_cpu(i, cmd->mask) { - work_on_cpu(i, do_drv_write, cmd); - } + smp_call_function_many(cmd->mask, do_drv_write, cmd, 1); } static u32 get_cur_val(const struct cpumask *mask) @@ -241,28 +238,23 @@ static u32 get_cur_val(const struct cpumask *mask) return cmd.val; } -struct perf_cur { +struct perf_pair { union { struct { u32 lo; u32 hi; } split; u64 whole; - } aperf_cur, mperf_cur; + } aperf, mperf; }; - -static long read_measured_perf_ctrs(void *_cur) +/* Called via smp_call_function_single(), on the target CPU */ +static void read_measured_perf_ctrs(void *_cur) { - struct perf_cur *cur = _cur; - - rdmsr(MSR_IA32_APERF, cur->aperf_cur.split.lo, cur->aperf_cur.split.hi); - rdmsr(MSR_IA32_MPERF, cur->mperf_cur.split.lo, cur->mperf_cur.split.hi); - - wrmsr(MSR_IA32_APERF, 0, 0); - wrmsr(MSR_IA32_MPERF, 0, 0); + struct perf_pair *cur = _cur; - return 0; + rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi); + rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi); } /* @@ -281,52 +273,57 @@ static long read_measured_perf_ctrs(void *_cur) static unsigned int get_measured_perf(struct cpufreq_policy *policy, unsigned int cpu) { - struct perf_cur cur; + struct perf_pair readin, cur; unsigned int perf_percent; unsigned int retval; - if (!work_on_cpu(cpu, read_measured_perf_ctrs, &cur)) + if (smp_call_function_single(cpu, read_measured_perf_ctrs, &readin, 1)) return 0; + cur.aperf.whole = readin.aperf.whole - + per_cpu(drv_data, cpu)->saved_aperf; + cur.mperf.whole = readin.mperf.whole - + per_cpu(drv_data, cpu)->saved_mperf; + per_cpu(drv_data, cpu)->saved_aperf = readin.aperf.whole; + per_cpu(drv_data, cpu)->saved_mperf = readin.mperf.whole; + #ifdef __i386__ /* * We dont want to do 64 bit divide with 32 bit kernel * Get an approximate value. Return failure in case we cannot get * an approximate value. */ - if (unlikely(cur.aperf_cur.split.hi || cur.mperf_cur.split.hi)) { + if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) { int shift_count; u32 h; - h = max_t(u32, cur.aperf_cur.split.hi, cur.mperf_cur.split.hi); + h = max_t(u32, cur.aperf.split.hi, cur.mperf.split.hi); shift_count = fls(h); - cur.aperf_cur.whole >>= shift_count; - cur.mperf_cur.whole >>= shift_count; + cur.aperf.whole >>= shift_count; + cur.mperf.whole >>= shift_count; } - if (((unsigned long)(-1) / 100) < cur.aperf_cur.split.lo) { + if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) { int shift_count = 7; - cur.aperf_cur.split.lo >>= shift_count; - cur.mperf_cur.split.lo >>= shift_count; + cur.aperf.split.lo >>= shift_count; + cur.mperf.split.lo >>= shift_count; } - if (cur.aperf_cur.split.lo && cur.mperf_cur.split.lo) - perf_percent = (cur.aperf_cur.split.lo * 100) / - cur.mperf_cur.split.lo; + if (cur.aperf.split.lo && cur.mperf.split.lo) + perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo; else perf_percent = 0; #else - if (unlikely(((unsigned long)(-1) / 100) < cur.aperf_cur.whole)) { + if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) { int shift_count = 7; - cur.aperf_cur.whole >>= shift_count; - cur.mperf_cur.whole >>= shift_count; + cur.aperf.whole >>= shift_count; + cur.mperf.whole >>= shift_count; } - if (cur.aperf_cur.whole && cur.mperf_cur.whole) - perf_percent = (cur.aperf_cur.whole * 100) / - cur.mperf_cur.whole; + if (cur.aperf.whole && cur.mperf.whole) + perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole; else perf_percent = 0; diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c index 0bd48e6..ce2ed3e 100644 --- a/arch/x86/kernel/cpu/cpufreq/longhaul.c +++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c @@ -33,7 +33,6 @@ #include <linux/timex.h> #include <linux/io.h> #include <linux/acpi.h> -#include <linux/kernel.h> #include <asm/msr.h> #include <acpi/processor.h> diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 70a10ca..18dfa30 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -18,6 +18,8 @@ #include <linux/init.h> #include <linux/list.h> +#include <trace/syscall.h> + #include <asm/cacheflush.h> #include <asm/ftrace.h> #include <asm/nops.h> diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 3aaf7b9..c3fe010 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -65,7 +65,7 @@ static int show_other_interrupts(struct seq_file *p, int prec) seq_printf(p, " Spurious interrupts\n"); #endif if (generic_interrupt_extension) { - seq_printf(p, "PLT: "); + seq_printf(p, "%*s: ", prec, "PLT"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->generic_irqs); seq_printf(p, " Platform interrupts\n"); diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index a0f3851..2e0eb41 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -108,40 +108,29 @@ struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; EXPORT_SYMBOL_GPL(ucode_cpu_info); #ifdef CONFIG_MICROCODE_OLD_INTERFACE -struct update_for_cpu { - const void __user *buf; - size_t size; -}; - -static long update_for_cpu(void *_ufc) -{ - struct update_for_cpu *ufc = _ufc; - int error; - - error = microcode_ops->request_microcode_user(smp_processor_id(), - ufc->buf, ufc->size); - if (error < 0) - return error; - if (!error) - microcode_ops->apply_microcode(smp_processor_id()); - return error; -} - static int do_microcode_update(const void __user *buf, size_t size) { + cpumask_t old; int error = 0; int cpu; - struct update_for_cpu ufc = { .buf = buf, .size = size }; + + old = current->cpus_allowed; for_each_online_cpu(cpu) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu; if (!uci->valid) continue; - error = work_on_cpu(cpu, update_for_cpu, &ufc); + + set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); + error = microcode_ops->request_microcode_user(cpu, buf, size); if (error < 0) - break; + goto out; + if (!error) + microcode_ops->apply_microcode(cpu); } +out: + set_cpus_allowed_ptr(current, &old); return error; } diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index dce99dc..70fd7e4 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -679,7 +679,7 @@ void __init get_smp_config(void) __get_smp_config(0); } -static void smp_reserve_bootmem(struct mpf_intel *mpf) +static void __init smp_reserve_bootmem(struct mpf_intel *mpf) { unsigned long size = get_mpc_size(mpf->physptr); #ifdef CONFIG_X86_32 @@ -838,7 +838,7 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m) static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; -static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) +static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) { int i; @@ -866,7 +866,8 @@ static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) } } #else /* CONFIG_X86_IO_APIC */ -static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} +static +inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} #endif /* CONFIG_X86_IO_APIC */ static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index fe9345c..23b7c8f 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -21,7 +21,6 @@ #include <linux/audit.h> #include <linux/seccomp.h> #include <linux/signal.h> -#include <linux/ftrace.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -35,6 +34,8 @@ #include <asm/proto.h> #include <asm/ds.h> +#include <trace/syscall.h> + #include "tls.h" enum x86_regset { diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 2aef36d..1340dad 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -224,6 +224,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), }, }, + { /* Handle problems with rebooting on Dell DXP061 */ + .callback = set_bios_reboot, + .ident = "Dell DXP061", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"), + }, + }, { } }; diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 2b54fe0..0a5b04a 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c @@ -324,7 +324,7 @@ void __ref xsave_cntxt_init(void) } /* - * for now OS knows only about FP/SSE + * Support only the state known to OS. */ pcntxt_mask = pcntxt_mask & XCNTXT_MASK; xsave_init(); diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index be54176..6340cef 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c @@ -219,6 +219,22 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, return 1; } +/** + * get_user_pages_fast() - pin user pages in memory + * @start: starting user address + * @nr_pages: number of pages from start to pin + * @write: whether pages will be written to + * @pages: array that receives pointers to the pages pinned. + * Should be at least nr_pages long. + * + * Attempt to pin user pages in memory without taking mm->mmap_sem. + * If not successful, it will fall back to taking the lock and + * calling get_user_pages(). + * + * Returns number of pages pinned. This may be fewer than the number + * requested. If nr_pages is 0 or negative, returns 0. If no pages + * were pinned, returns -errno. + */ int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages) { diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 0dfa09d..09daebf 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -547,7 +547,7 @@ void __init early_ioremap_reset(void) } static void __init __early_set_fixmap(enum fixed_addresses idx, - unsigned long phys, pgprot_t flags) + phys_addr_t phys, pgprot_t flags) { unsigned long addr = __fix_to_virt(idx); pte_t *pte; @@ -566,7 +566,7 @@ static void __init __early_set_fixmap(enum fixed_addresses idx, } static inline void __init early_set_fixmap(enum fixed_addresses idx, - unsigned long phys, pgprot_t prot) + phys_addr_t phys, pgprot_t prot) { if (after_paging_init) __set_fixmap(idx, phys, prot); @@ -607,9 +607,10 @@ static int __init check_early_ioremap_leak(void) late_initcall(check_early_ioremap_leak); static void __init __iomem * -__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) +__early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot) { - unsigned long offset, last_addr; + unsigned long offset; + resource_size_t last_addr; unsigned int nrpages; enum fixed_addresses idx0, idx; int i, slot; @@ -625,15 +626,15 @@ __early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) } if (slot < 0) { - printk(KERN_INFO "early_iomap(%08lx, %08lx) not found slot\n", - phys_addr, size); + printk(KERN_INFO "early_iomap(%08llx, %08lx) not found slot\n", + (u64)phys_addr, size); WARN_ON(1); return NULL; } if (early_ioremap_debug) { - printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ", - phys_addr, size, slot); + printk(KERN_INFO "early_ioremap(%08llx, %08lx) [%d] => ", + (u64)phys_addr, size, slot); dump_stack(); } @@ -680,13 +681,15 @@ __early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) } /* Remap an IO device */ -void __init __iomem *early_ioremap(unsigned long phys_addr, unsigned long size) +void __init __iomem * +early_ioremap(resource_size_t phys_addr, unsigned long size) { return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO); } /* Remap memory */ -void __init __iomem *early_memremap(unsigned long phys_addr, unsigned long size) +void __init __iomem * +early_memremap(resource_size_t phys_addr, unsigned long size) { return __early_ioremap(phys_addr, size, PAGE_KERNEL); } diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 640339e..c009a24 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -31,7 +31,7 @@ #ifdef CONFIG_X86_PAT int __read_mostly pat_enabled = 1; -void __cpuinit pat_disable(const char *reason) +static inline void pat_disable(const char *reason) { pat_enabled = 0; printk(KERN_INFO "%s\n", reason); diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 5b7c7c8..7aa03a5 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -345,7 +345,8 @@ void __native_set_fixmap(enum fixed_addresses idx, pte_t pte) fixmaps_set++; } -void native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags) +void native_set_fixmap(enum fixed_addresses idx, phys_addr_t phys, + pgprot_t flags) { __native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags)); } diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 82cd39a..f09e8c3 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -42,6 +42,7 @@ #include <asm/xen/hypervisor.h> #include <asm/fixmap.h> #include <asm/processor.h> +#include <asm/proto.h> #include <asm/msr-index.h> #include <asm/setup.h> #include <asm/desc.h> @@ -168,21 +169,23 @@ static void __init xen_banner(void) xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); } +static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; +static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; + static void xen_cpuid(unsigned int *ax, unsigned int *bx, unsigned int *cx, unsigned int *dx) { + unsigned maskecx = ~0; unsigned maskedx = ~0; /* * Mask out inconvenient features, to try and disable as many * unsupported kernel subsystems as possible. */ - if (*ax == 1) - maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ - (1 << X86_FEATURE_ACPI) | /* disable ACPI */ - (1 << X86_FEATURE_MCE) | /* disable MCE */ - (1 << X86_FEATURE_MCA) | /* disable MCA */ - (1 << X86_FEATURE_ACC)); /* thermal monitoring */ + if (*ax == 1) { + maskecx = cpuid_leaf1_ecx_mask; + maskedx = cpuid_leaf1_edx_mask; + } asm(XEN_EMULATE_PREFIX "cpuid" : "=a" (*ax), @@ -190,9 +193,43 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, "=c" (*cx), "=d" (*dx) : "0" (*ax), "2" (*cx)); + + *cx &= maskecx; *dx &= maskedx; } +static __init void xen_init_cpuid_mask(void) +{ + unsigned int ax, bx, cx, dx; + + cpuid_leaf1_edx_mask = + ~((1 << X86_FEATURE_MCE) | /* disable MCE */ + (1 << X86_FEATURE_MCA) | /* disable MCA */ + (1 << X86_FEATURE_ACC)); /* thermal monitoring */ + + if (!xen_initial_domain()) + cpuid_leaf1_edx_mask &= + ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ + (1 << X86_FEATURE_ACPI)); /* disable ACPI */ + + ax = 1; + xen_cpuid(&ax, &bx, &cx, &dx); + + /* cpuid claims we support xsave; try enabling it to see what happens */ + if (cx & (1 << (X86_FEATURE_XSAVE % 32))) { + unsigned long cr4; + + set_in_cr4(X86_CR4_OSXSAVE); + + cr4 = read_cr4(); + + if ((cr4 & X86_CR4_OSXSAVE) == 0) + cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32)); + + clear_in_cr4(X86_CR4_OSXSAVE); + } +} + static void xen_set_debugreg(int reg, unsigned long val) { HYPERVISOR_set_debugreg(reg, val); @@ -284,12 +321,11 @@ static void xen_set_ldt(const void *addr, unsigned entries) static void xen_load_gdt(const struct desc_ptr *dtr) { - unsigned long *frames; unsigned long va = dtr->address; unsigned int size = dtr->size + 1; unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; + unsigned long frames[pages]; int f; - struct multicall_space mcs; /* A GDT can be up to 64k in size, which corresponds to 8192 8-byte entries, or 16 4k pages.. */ @@ -297,19 +333,26 @@ static void xen_load_gdt(const struct desc_ptr *dtr) BUG_ON(size > 65536); BUG_ON(va & ~PAGE_MASK); - mcs = xen_mc_entry(sizeof(*frames) * pages); - frames = mcs.args; - for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { - frames[f] = arbitrary_virt_to_mfn((void *)va); + int level; + pte_t *ptep = lookup_address(va, &level); + unsigned long pfn, mfn; + void *virt; + + BUG_ON(ptep == NULL); + + pfn = pte_pfn(*ptep); + mfn = pfn_to_mfn(pfn); + virt = __va(PFN_PHYS(pfn)); + + frames[f] = mfn; make_lowmem_page_readonly((void *)va); - make_lowmem_page_readonly(mfn_to_virt(frames[f])); + make_lowmem_page_readonly(virt); } - MULTI_set_gdt(mcs.mc, frames, size / sizeof(struct desc_struct)); - - xen_mc_issue(PARAVIRT_LAZY_CPU); + if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct))) + BUG(); } static void load_TLS_descriptor(struct thread_struct *t, @@ -385,7 +428,7 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum, static int cvt_gate_to_trap(int vector, const gate_desc *val, struct trap_info *info) { - if (val->type != 0xf && val->type != 0xe) + if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT) return 0; info->vector = vector; @@ -393,8 +436,8 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val, info->cs = gate_segment(*val); info->flags = val->dpl; /* interrupt gates clear IF */ - if (val->type == 0xe) - info->flags |= 4; + if (val->type == GATE_INTERRUPT) + info->flags |= 1 << 2; return 1; } @@ -872,7 +915,6 @@ static const struct machine_ops __initdata xen_machine_ops = { .emergency_restart = xen_emergency_restart, }; - /* First C function to be called on Xen boot */ asmlinkage void __init xen_start_kernel(void) { @@ -897,6 +939,8 @@ asmlinkage void __init xen_start_kernel(void) xen_init_irq_ops(); + xen_init_cpuid_mask(); + #ifdef CONFIG_X86_LOCAL_APIC /* * set up the basic apic ops. @@ -938,6 +982,11 @@ asmlinkage void __init xen_start_kernel(void) if (!xen_initial_domain()) __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD); +#ifdef CONFIG_X86_64 + /* Work out if we support NX */ + check_efer(); +#endif + /* Don't do the full vcpu_info placement stuff until we have a possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index db3802f..9842b12 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -184,7 +184,7 @@ static inline unsigned p2m_index(unsigned long pfn) } /* Build the parallel p2m_top_mfn structures */ -void xen_setup_mfn_list_list(void) +static void __init xen_build_mfn_list_list(void) { unsigned pfn, idx; @@ -198,7 +198,10 @@ void xen_setup_mfn_list_list(void) unsigned topidx = idx * P2M_ENTRIES_PER_PAGE; p2m_top_mfn_list[idx] = virt_to_mfn(&p2m_top_mfn[topidx]); } +} +void xen_setup_mfn_list_list(void) +{ BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = @@ -218,6 +221,8 @@ void __init xen_build_dynamic_phys_to_machine(void) p2m_top[topidx] = &mfn_list[pfn]; } + + xen_build_mfn_list_list(); } unsigned long get_phys_to_machine(unsigned long pfn) @@ -233,47 +238,74 @@ unsigned long get_phys_to_machine(unsigned long pfn) } EXPORT_SYMBOL_GPL(get_phys_to_machine); -static void alloc_p2m(unsigned long **pp, unsigned long *mfnp) +/* install a new p2m_top page */ +bool install_p2mtop_page(unsigned long pfn, unsigned long *p) { - unsigned long *p; + unsigned topidx = p2m_top_index(pfn); + unsigned long **pfnp, *mfnp; unsigned i; - p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL); - BUG_ON(p == NULL); + pfnp = &p2m_top[topidx]; + mfnp = &p2m_top_mfn[topidx]; for (i = 0; i < P2M_ENTRIES_PER_PAGE; i++) p[i] = INVALID_P2M_ENTRY; - if (cmpxchg(pp, p2m_missing, p) != p2m_missing) - free_page((unsigned long)p); - else + if (cmpxchg(pfnp, p2m_missing, p) == p2m_missing) { *mfnp = virt_to_mfn(p); + return true; + } + + return false; } -void set_phys_to_machine(unsigned long pfn, unsigned long mfn) +static void alloc_p2m(unsigned long pfn) { - unsigned topidx, idx; + unsigned long *p; - if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { - BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); - return; - } + p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL); + BUG_ON(p == NULL); + + if (!install_p2mtop_page(pfn, p)) + free_page((unsigned long)p); +} + +/* Try to install p2m mapping; fail if intermediate bits missing */ +bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) +{ + unsigned topidx, idx; if (unlikely(pfn >= MAX_DOMAIN_PAGES)) { BUG_ON(mfn != INVALID_P2M_ENTRY); - return; + return true; } topidx = p2m_top_index(pfn); if (p2m_top[topidx] == p2m_missing) { - /* no need to allocate a page to store an invalid entry */ if (mfn == INVALID_P2M_ENTRY) - return; - alloc_p2m(&p2m_top[topidx], &p2m_top_mfn[topidx]); + return true; + return false; } idx = p2m_index(pfn); p2m_top[topidx][idx] = mfn; + + return true; +} + +void set_phys_to_machine(unsigned long pfn, unsigned long mfn) +{ + if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { + BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); + return; + } + + if (unlikely(!__set_phys_to_machine(pfn, mfn))) { + alloc_p2m(pfn); + + if (!__set_phys_to_machine(pfn, mfn)) + BUG(); + } } unsigned long arbitrary_virt_to_mfn(void *vaddr) @@ -987,7 +1019,7 @@ static __init int xen_mark_pinned(struct mm_struct *mm, struct page *page, return 0; } -void __init xen_mark_init_mm_pinned(void) +static void __init xen_mark_init_mm_pinned(void) { xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP); } @@ -1270,8 +1302,8 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, } *args; struct multicall_space mcs; - BUG_ON(cpumask_empty(cpus)); - BUG_ON(!mm); + if (cpumask_empty(cpus)) + return; /* nothing to do */ mcs = xen_mc_entry(sizeof(*args)); args = mcs.args; @@ -1438,6 +1470,15 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte) } #endif +static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) +{ + struct mmuext_op op; + op.cmd = cmd; + op.arg1.mfn = pfn_to_mfn(pfn); + if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) + BUG(); +} + /* Early in boot, while setting up the initial pagetable, assume everything is pinned. */ static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) @@ -1446,22 +1487,29 @@ static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) BUG_ON(mem_map); /* should only be used early */ #endif make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); + pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); +} + +/* Used for pmd and pud */ +static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn) +{ +#ifdef CONFIG_FLATMEM + BUG_ON(mem_map); /* should only be used early */ +#endif + make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); } /* Early release_pte assumes that all pts are pinned, since there's only init_mm and anything attached to that is pinned. */ -static void xen_release_pte_init(unsigned long pfn) +static __init void xen_release_pte_init(unsigned long pfn) { + pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); } -static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) +static __init void xen_release_pmd_init(unsigned long pfn) { - struct mmuext_op op; - op.cmd = cmd; - op.arg1.mfn = pfn_to_mfn(pfn); - if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) - BUG(); + make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); } /* This needs to make sure the new pte page is pinned iff its being @@ -1750,7 +1798,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, } #endif /* CONFIG_X86_64 */ -static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot) +static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) { pte_t pte; @@ -1773,6 +1821,9 @@ static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot) #ifdef CONFIG_X86_LOCAL_APIC case FIX_APIC_BASE: /* maps dummy local APIC */ #endif + case FIX_TEXT_POKE0: + case FIX_TEXT_POKE1: + /* All local page mappings */ pte = pfn_pte(phys, prot); break; @@ -1819,7 +1870,6 @@ __init void xen_post_allocator_init(void) xen_mark_init_mm_pinned(); } - const struct pv_mmu_ops xen_mmu_ops __initdata = { .pagetable_setup_start = xen_pagetable_setup_start, .pagetable_setup_done = xen_pagetable_setup_done, @@ -1843,9 +1893,9 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = { .alloc_pte = xen_alloc_pte_init, .release_pte = xen_release_pte_init, - .alloc_pmd = xen_alloc_pte_init, + .alloc_pmd = xen_alloc_pmd_init, .alloc_pmd_clone = paravirt_nop, - .release_pmd = xen_release_pte_init, + .release_pmd = xen_release_pmd_init, #ifdef CONFIG_HIGHPTE .kmap_atomic_pte = xen_kmap_atomic_pte, @@ -1883,8 +1933,8 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = { .make_pud = PV_CALLEE_SAVE(xen_make_pud), .set_pgd = xen_set_pgd_hyper, - .alloc_pud = xen_alloc_pte_init, - .release_pud = xen_release_pte_init, + .alloc_pud = xen_alloc_pmd_init, + .release_pud = xen_release_pmd_init, #endif /* PAGETABLE_LEVELS == 4 */ .activate_mm = xen_activate_mm, diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h index 24d1b44..da73026 100644 --- a/arch/x86/xen/mmu.h +++ b/arch/x86/xen/mmu.h @@ -11,6 +11,9 @@ enum pt_level { }; +bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); +bool install_p2mtop_page(unsigned long pfn, unsigned long *p); + void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 585a6e3..429834e 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -317,7 +317,7 @@ static int __cpuinit xen_cpu_up(unsigned int cpu) BUG_ON(rc); while(per_cpu(cpu_state, cpu) != CPU_ONLINE) { - HYPERVISOR_sched_op(SCHEDOP_yield, 0); + HYPERVISOR_sched_op(SCHEDOP_yield, NULL); barrier(); } @@ -422,7 +422,7 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask) /* Make sure other vcpus get a chance to run if they need to. */ for_each_cpu(cpu, mask) { if (xen_vcpu_stolen(cpu)) { - HYPERVISOR_sched_op(SCHEDOP_yield, 0); + HYPERVISOR_sched_op(SCHEDOP_yield, NULL); break; } } diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 2f5ef26..2013946 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -57,8 +57,6 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id); bool xen_vcpu_stolen(int vcpu); -void xen_mark_init_mm_pinned(void); - void xen_setup_vcpu_info_placement(void); #ifdef CONFIG_SMP |