diff --git a/dde_linux/Makefile b/dde_linux/Makefile index 7221007dd..d87ad8a1a 100644 --- a/dde_linux/Makefile +++ b/dde_linux/Makefile @@ -7,7 +7,7 @@ CONTRIB_DIR = contrib DOWNLOAD_DIR = download VERBOSE ?= @ ECHO = @echo -PATCHES = $(shell find patches -name *.patch) +PATCHES := $(shell find patches -name \*.patch) LINUX = linux-3.2.2 LINUX_TBZ2 = $(LINUX).tar.bz2 @@ -31,7 +31,7 @@ CONTENT += include/linux/usbdevice_fs.h include/asm-generic/ioctl.h # USB host-controller driver CONTENT_USB_HOST := ehci.h ehci-hcd.c ehci-hub.c ehci-dbg.c ehci-mem.c \ - ehci-q.c ehci-pci.c ehci-sched.c ehci-sysfs.c + ehci-omap.c ehci-q.c ehci-pci.c ehci-sched.c ehci-sysfs.c CONTENT_USB_HOST += ohci.h ohci-hcd.c ohci-hub.c ohci-dbg.c ohci-mem.c \ ohci-q.c ohci-pci.c ehci-lpm.c CONTENT_USB_HOST += uhci-hcd.h uhci-hcd.c uhci-debug.c uhci-q.c uhci-hub.c \ @@ -57,7 +57,12 @@ CONTENT += $(addprefix drivers/input/,$(CONTENT_INPUT)) CONTENT += include/linux/input/mt.h -CONTRIB_CONTENT := $(addprefix $(CONTRIB_DIR)/,$(CONTENT)) +# Panda board +#CONTENT += drivers/mfd/omap-usb-host.c +#CONTENT += arch/arm/plat-omap/include/plat/usb.h +#CONTENT_ARCH = usb-host.c mux.h mux2420.h mux2430.h mux34xx.h mux44xx.h +#CONTENT += $(addprefix arch/arm/mach-omap2/,$(CONTENT_ARCH)) +#CONTRIB_CONTENT := $(addprefix $(CONTRIB_DIR)/,$(CONTENT)) # # # Utility to check if a tool is installed @@ -100,7 +105,7 @@ $(DOWNLOAD_DIR)/$(LINUX_TBZ2): $(DOWNLOAD_DIR) $(VERBOSE)touch $@ clean: - $(VERBOSE)rm -f $(CONTRIB_DIR) + $(VERBOSE)rm -rf $(CONTRIB_DIR) cleanall: clean $(VERBOSE)rm -rf $(DOWNLOAD_DIR) diff --git a/dde_linux/src/drivers/usb/arm/platform/lx_emul.h b/dde_linux/src/drivers/usb/arm/platform/lx_emul.h new file mode 100644 index 000000000..b814780c3 --- /dev/null +++ b/dde_linux/src/drivers/usb/arm/platform/lx_emul.h @@ -0,0 +1,178 @@ +/* + * \brief Platform specific part of the Linux API emulation + * \author Sebastian Sumpf + * \date 2012-06-18 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ +#ifndef _ARM__PLATFORM__LX_EMUL_H_ +#define _ARM__PLATFORM__LX_EMUL_H_ + +/************************* + ** asm-generic/sizes.h ** + *************************/ + +enum { + SZ_1K = 0x00000400, + SZ_4K = 0x00001000a, +}; + +struct platform_device +{ + const char *name; + int id; + struct device dev; + u32 num_resources; + struct resource *resource; +}; + + +/********************** + ** linux/usb/ulpi.h ** + **********************/ + +enum { + ULPI_FUNC_CTRL_RESET = (1 << 5), + ULPI_FUNC_CTRL = (1 << 2), +}; + +/* + * Macros for Set and Clear + * See ULPI 1.1 specification to find the registers with Set and Clear offsets + */ + +#define ULPI_SET(a) (a + 1) + +/******************************************* + ** arch/arm/plat-omap/include/plat/usb.h ** + *******************************************/ + +enum { OMAP3_HS_USB_PORTS = 2 }; + +enum usbhs_omap_port_mode +{ + OMAP_EHCI_PORT_MODE_NONE, + OMAP_EHCI_PORT_MODE_PHY, +}; + + +struct ehci_hcd_omap_platform_data +{ + enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; + struct regulator *regulator[OMAP3_HS_USB_PORTS]; +}; + +struct regulator; +/********************************************* + ** arch/arm/plat-omap/include/plat/board.h ** + *********************************************/ + +struct omap_usb_config; + + +/************************************************ + ** arch/arm/plat-omap/include/plat/omap34xx.h ** + ************************************************/ + +#define OMAP34XX_UHH_CONFIG_BASE 0 +#define OMAP34XX_EHCI_BASE 0 +#define OMAP34XX_USBTLL_BASE 0 +#define INT_34XX_EHCI_IRQ 0 +#define OMAP34XX_OHCI_BASE 0 +#define INT_34XX_OHCI_IRQ 0 +#define OMAP3430_REV_ES2_1 0 + + +static inline int cpu_is_omap34xx(void) { return 0; } +static inline int cpu_is_omap3430(void) { return 0; } + +/*************************************************** + ** platform definition os for OMAP44xx all under ** + ** 'arch/arm/plat-omap/include ** + ***************************************************/ + +enum { + OMAP44XX_IRQ_GIC_START = 32, + OMAP44XX_IRQ_EHCI = 77 + OMAP44XX_IRQ_GIC_START, + OMAP44XX_IRQ_OHCI =76 + OMAP44XX_IRQ_GIC_START, +}; + +enum { + L4_44XX_BASE = 0x4a000000, + OMAP44XX_USBTLL_BASE = L4_44XX_BASE + 0x62000, + OMAP44XX_UHH_CONFIG_BASE = L4_44XX_BASE + 0x64000, + OMAP44XX_HSUSB_OHCI_BASE = L4_44XX_BASE + 0x64800, + OMAP44XX_HSUSB_EHCI_BASE = L4_44XX_BASE + 0x64C00, +}; + +static inline int cpu_is_omap44xx(void) { return 1; } + +/***************************** + ** linux/platform_device.h ** + *****************************/ + +struct platform_driver { + int (*probe)(struct platform_device *); + int (*remove)(struct platform_device *); + void (*shutdown)(struct platform_device *); + int (*suspend)(struct platform_device *, pm_message_t state); + int (*resume)(struct platform_device *); + struct device_driver driver; + const struct platform_device_id *id_table; +}; + +struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *); +int platform_get_irq_byname(struct platform_device *, const char *); + +int platform_driver_register(struct platform_driver *); +int platform_device_register(struct platform_device *); + +/********************** + ** asm/generic/io.h ** + **********************/ + +static inline u32 __raw_readl(const volatile void __iomem *addr) +{ + return *(const volatile u32 __force *) addr; +} + +static inline void __raw_writel(u32 b, volatile void __iomem *addr) +{ + *(volatile u32 __force *) addr = b; +} + + +static inline u8 __raw_readb(const volatile void __iomem *addr) +{ + return *(const volatile u8 __force *) addr; +} + +static inline void __raw_writeb(u8 b, volatile void __iomem *addr) +{ + *(volatile u8 __force *) addr = b; +} + + +/******************************** + ** linux/regulator/consumer.h ** + ********************************/ + +int regulator_enable(struct regulator *); +int regulator_disable(struct regulator *); +void regulator_put(struct regulator *regulator); +struct regulator *regulator_get(struct device *dev, const char *id); + + +/******************************************* + ** arch/arm/plat-omap/include/plat/usb.h ** + *******************************************/ + +int omap_usbhs_enable(struct device *dev); +void omap_usbhs_disable(struct device *dev); + +#endif /* _ARM__PLATFORM__LX_EMUL_H_ */ diff --git a/dde_linux/src/drivers/usb/arm/platform/platform.cc b/dde_linux/src/drivers/usb/arm/platform/platform.cc new file mode 100644 index 000000000..26cbc024d --- /dev/null +++ b/dde_linux/src/drivers/usb/arm/platform/platform.cc @@ -0,0 +1,395 @@ +/** + * \brief EHCI for OMAP4 + * \author Sebastian Sumpf + * \date 2012-06-20 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +#include +#include + +#include + +using namespace Genode; + +/** + * Base addresses + */ +enum { + EHCI_BASE = 0x4a064c00, + UHH_BASE = 0x4a064000, + TLL_BASE = 0x4a062000, + SCRM_BASE = 0x4a30a000, + CAM_BASE = 0x4a009000, /* used for L3INIT_CM2 */ +}; + + +/** + * Inerrupt numbers + */ +enum { + IRQ_GIC_START = 32, + IRQ_EHCI = IRQ_GIC_START + 77, +}; + + +/** + * Resources for platform device + */ +static resource _ehci[] = +{ + { EHCI_BASE, EHCI_BASE + 0x400 - 1, "ehci", IORESOURCE_MEM }, + { IRQ_EHCI, IRQ_EHCI, "ehci-irq", IORESOURCE_IRQ }, +}; + + +/** + * Port informations for platform device + */ +static struct ehci_hcd_omap_platform_data _ehci_data +{ + { OMAP_EHCI_PORT_MODE_PHY, OMAP_EHCI_PORT_MODE_NONE }, + { 0, 0 } +}; + + +extern "C" void module_ehci_hcd_init(); + + +/** + * Enables USB clocks + */ +struct Clocks : Genode::Mmio +{ + Clocks(Genode::addr_t const mmio_base) : Mmio(mmio_base) + { + write(0x101); + write(0x1008002); + write(0x1); + } + + struct Usb_host_clk : Register<0x358, 32> { }; + struct Usb_tll_clk : Register<0x368, 32> { }; + struct Usb_phy_clk : Register<0x3e0, 32> { }; + + template void update(unsigned val) + { + typename T::access_t access = read(); + access |= val; + write(access); + }; + + void dump() + { + Usb_host_clk::access_t a1 = read(); + PDBG("Host clock %x", a1); + Usb_tll_clk::access_t a3 = read(); + PDBG("TLL: %x", a3); + Usb_phy_clk::access_t a4 = read(); + PDBG("Phy: %x", a4); + } +}; + + +/** + * Panda board reference USB clock + */ +struct Aux3 : Genode::Mmio +{ + Aux3(addr_t const mmio_base) : Mmio(mmio_base) + { + enable(); + } + + /* the clock register */ + struct Aux3_clk : Register<0x31c, 32> + { + struct Src_select : Bitfield<1, 2> { }; + struct Div : Bitfield<16, 4> { enum { DIV_2 = 1 }; }; + struct Enable : Bitfield<8, 1> { enum { ON = 1 }; }; + }; + + /* clock source register */ + struct Aux_src : Register<0x110, 32, true> { }; + + void enable() + { + /* select system clock */ + write(0); + + /* set to 19.2 Mhz */ + write(Aux3_clk::Div::DIV_2); + + /* enable clock */ + write(Aux3_clk::Enable::ON); + + /* enable_ext = 1 | enable_int = 1| mode = 0x01 */ + write(0xd); + } +}; + + +/** + * ULPI transceiverless link + */ +struct Tll : Genode::Mmio +{ + Tll(addr_t const mmio_base) : Mmio(mmio_base) + { + reset(); + } + + struct Sys_config : Register<0x10, 32> + { + struct Soft_reset : Bitfield<1, 1> { }; + struct Cactivity : Bitfield<8, 1> { }; + struct Sidle_mode : Bitfield<3, 2> { }; + struct Ena_wakeup : Bitfield<2, 1> { }; + }; + + struct Sys_status : Register<0x14, 32> { }; + + void reset() + { + write(0x0); + + /* reset */ + write(0x1); + + while(!read()) + msleep(1); + + /* disable IDLE, enable wake up, enable auto gating */ + write(1); + write(1); + write(1); + } +}; + + +/** + * USB high-speed host + */ +struct Uhh : Genode::Mmio +{ + Uhh(addr_t const mmio_base) : Mmio(mmio_base) + { + /* diable idle and standby */ + write(1); + write(1); + + /* set ports to external phy */ + write(0); + write(0); + } + + struct Sys_config : Register<0x10, 32> + { + struct Idle : Bitfield<2, 2> { }; + struct Standby : Bitfield<4, 2> { }; + }; + + struct Host_config : Register<0x40, 32> + { + struct P1_mode : Bitfield<16, 2> { }; + struct P2_mode : Bitfield<18, 2> { }; + }; +}; + + +/** + * EHCI controller + */ +struct Ehci : Genode::Mmio +{ + Ehci(addr_t const mmio_base) : Mmio(mmio_base) + { + write(0); + + /* reset */ + write(1); + + while(read()) + msleep(1); + } + + struct Cmd : Register<0x10, 32> + { + struct Reset : Bitfield<1, 1> { }; + }; +}; + + +/** + * Panda board GPIO bases 1 - 6 + */ +static addr_t omap44xx_gpio_base[] = +{ + 0x4A310000, 0x48055000, 0x48057000, 0x48059000, 0x4805B000, 0x4805D000 +}; + + +/** + * General purpose I/O + */ +struct Gpio +{ + enum { GPIO = 6 }; + + addr_t _io[GPIO]; + Io_mem_session_capability _cap[GPIO]; + + void map() + { + for (int i = 0; i < GPIO; i++) { + Io_mem_connection io(omap44xx_gpio_base[i], 0x1000); + io.on_destruction(Io_mem_connection::KEEP_OPEN); + _io[i] = (addr_t)env()->rm_session()->attach(io.dataspace()); + _cap[i] = io.cap(); + } + } + + Gpio() + { + map(); + } + + ~Gpio() + { + for (int i = 0; i < GPIO; i++) { + env()->rm_session()->detach(_io[i]); + env()->parent()->close(_cap[i]); + } + } + + addr_t base(unsigned gpio) { return _io[gpio >> 5]; } + int index(unsigned gpio) { return gpio & 0x1f; } + + void _set_data_out(addr_t base, unsigned gpio, bool enable) + { + enum { SETDATAOUT = 0x194, CLEARDATAOUT = 0x190 }; + writel(1U << gpio, base + (enable ? SETDATAOUT : CLEARDATAOUT)); + } + + void _set_gpio_direction(addr_t base, unsigned gpio, bool input) + { + enum { OE = 0x134 }; + base += OE; + + u32 val = readl(base); + + if (input) + val |= 1U << gpio; + else + val &= ~(1U << gpio); + + writel(val, base); + } + + void direction_output(unsigned gpio, bool enable) + { + _set_data_out(base(gpio), index(gpio), enable); + _set_gpio_direction(base(gpio), index(gpio), false); + } + + void direction_input(unsigned gpio) + { + _set_gpio_direction(base(gpio), index(gpio), true); + } + + void set_value(unsigned gpio, int val) + { + _set_data_out(base(gpio), index(gpio), val); + } + + unsigned get_value(int gpio) + { + enum { DATAIN = 0x138 }; + return (readl(base(gpio) + DATAIN) & (1 << index(gpio))) != 0; + } +}; + + +/** + * Initialize the USB controller from scratch, since the boot loader might not + * do it or even disable USB. + */ +static void omap_ehci_init() +{ + /* taken from the Panda board manual */ + enum { HUB_POWER = 1, HUB_NRESET = 62, ULPI_PHY_TYPE = 182 }; + + /* SCRM */ + Io_mem_connection io_scrm(SCRM_BASE, 0x1000); + addr_t scrm_base = (addr_t)env()->rm_session()->attach(io_scrm.dataspace()); + + /* enable reference clock */ + Aux3 aux3(scrm_base); + + /* init GPIO */ + Gpio gpio; + /* disable the hub power and reset before init */ + gpio.direction_output(HUB_POWER, false); + gpio.direction_output(HUB_NRESET, false); + gpio.set_value(HUB_POWER, 0); + gpio.set_value(HUB_NRESET, 1); + + /* enable clocks */ + Io_mem_connection io_clock(CAM_BASE, 0x1000); + addr_t clock_base = (addr_t)env()->rm_session()->attach(io_clock.dataspace()); + Clocks c(clock_base); + + /* reset TLL */ + Io_mem_connection io_tll(TLL_BASE, 0x1000); + addr_t tll_base = (addr_t)env()->rm_session()->attach(io_tll.dataspace()); + Tll t(tll_base); + + /* reset host */ + Io_mem_connection io_uhh(UHH_BASE, 0x1000); + addr_t uhh_base = (addr_t)env()->rm_session()->attach(io_uhh.dataspace()); + Uhh uhh(uhh_base); + + /* enable hub power */ + gpio.set_value(HUB_POWER, 1); + + /* reset EHCI */ + addr_t ehci_base = uhh_base + 0xc00; + Ehci ehci(ehci_base); + + addr_t base[] = { scrm_base, clock_base, tll_base, uhh_base, 0 }; + for (int i = 0; base[i]; i++) + env()->rm_session()->detach(base[i]); +} + + +void platform_hcd_init(void) +{ + module_ehci_hcd_init(); + omap_ehci_init(); + + /* setup EHCI-controller platform device */ + platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0); + pdev->name = "ehci-omap"; + pdev->id = 0; + pdev->num_resources = 2; + pdev->resource = _ehci; + pdev->dev.platform_data = &_ehci_data; + + /* + * Needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' + */ + static u64 dma_mask = ~(u32)0; + pdev->dev.dma_mask = &dma_mask; + pdev->dev.coherent_dma_mask = ~0; + + platform_device_register(pdev); +} + diff --git a/dde_linux/src/drivers/usb/arm/platform/platform.h b/dde_linux/src/drivers/usb/arm/platform/platform.h new file mode 100644 index 000000000..638e2f440 --- /dev/null +++ b/dde_linux/src/drivers/usb/arm/platform/platform.h @@ -0,0 +1,38 @@ +/** + * \brief Platform specific code + * \author Sebastian Sumpf + * \date 2012-06-10 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _ARM__PLATFORM_H_ +#define _ARM__PLATFORM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +static inline +void platform_execute(void *sp, void *func, void *arg) +{ + asm volatile ("mov r0, %2;" /* set arg */ + "mov sp, %0;" /* set stack */ + "mov pc, %1;" /* call func */ + "" + : : "r"(sp), "r"(func), "r"(arg) : "r0"); +} + + +void platform_hcd_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _ARM__PLATFORM_H_ */ diff --git a/dde_linux/src/drivers/usb/arm/platform/platform_device.c b/dde_linux/src/drivers/usb/arm/platform/platform_device.c new file mode 100644 index 000000000..7eaaea48d --- /dev/null +++ b/dde_linux/src/drivers/usb/arm/platform/platform_device.c @@ -0,0 +1,88 @@ +/* + * \brief Linux platform_device emulation + * \author Sebastian Sumpf + * \date 2012-06-18 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ + driver)) +#define to_platform_device(x) container_of((x), struct platform_device, dev) + + +static int platform_match(struct device *dev, struct device_driver *drv) +{ + if (!dev->name) + return 0; + + return (strcmp(dev->name, drv->name) == 0); +} + + +static int platform_drv_probe(struct device *_dev) +{ + struct platform_driver *drv = to_platform_driver(_dev->driver); + struct platform_device *dev = to_platform_device(_dev); + + return drv->probe(dev); +} + + +struct bus_type platform_bus_type = { + .name = "platform", + .match = platform_match, + .probe = platform_drv_probe +}; + + +int platform_driver_register(struct platform_driver *drv) +{ + drv->driver.bus = &platform_bus_type; + if (drv->probe) + drv->driver.probe = platform_drv_probe; + + return driver_register(&drv->driver); +} + + +struct resource *platform_get_resource_byname(struct platform_device *dev, + unsigned int type, + const char *name) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) { + struct resource *r = &dev->resource[i]; + + if (type == r->flags && !strcmp(r->name, name)) + return r; + } + + return NULL; +} + + +int platform_get_irq_byname(struct platform_device *dev, const char *name) +{ + struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); + return r ? r->start : -1; +} + + +int platform_device_register(struct platform_device *pdev) +{ + pdev->dev.bus = &platform_bus_type; + pdev->dev.name = pdev->name; + /* XXX: Fill with magic value to see page fault */ + pdev->dev.parent = (struct device *)0xaaaaaaaa; + device_add(&pdev->dev); + return 0; +} diff --git a/dde_linux/src/drivers/usb/dma.h b/dde_linux/src/drivers/usb/dma.h new file mode 100644 index 000000000..860c81839 --- /dev/null +++ b/dde_linux/src/drivers/usb/dma.h @@ -0,0 +1,94 @@ +/* + * \brief DMA memory pool + * \author Sebastian Sumpf + * \date 2012-06-18 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _DMA_H_ +#define _DMA_H_ + +#include +#include +#include + +/********************* + ** linux/dmapool.h ** + *********************/ + +namespace Genode { + + /** + * Dma-pool manager + */ + class Dma + { + private: + + enum { SIZE = 1024 * 1024 }; + + addr_t _base; /* virt base of pool */ + addr_t _base_phys; /* phys base of pool */ + Allocator_avl _range; /* range allocator for pool */ + + Dma() : _range(env()->heap()) + { + Ram_dataspace_capability cap = env()->ram_session()->alloc(SIZE); + _base_phys = Dataspace_client(cap).phys_addr(); + _base = (addr_t)env()->rm_session()->attach(cap); + dde_kit_log(DEBUG_DMA, "New DMA range [%lx-%lx)", _base, _base + SIZE); + _range.add_range(_base, SIZE); + } + + public: + + static Dma* pool() + { + static Dma _p; + return &_p; + } + + addr_t base() const { return _base; }; + addr_t end() const { return _base + SIZE -1; } + + /** + * Alloc 'size' bytes of DMA memory + */ + void *alloc(size_t size, int align = 12) + { + void *addr; + if (!_range.alloc_aligned(size, &addr, align)) { + PERR("DMA of %zu bytes allocation failed", size); + return 0; + } + + return addr; + } + + /** + * Free DMA memory + */ + void free(void *addr) { _range.free(addr); } + + /** + * Get phys for virt address + */ + addr_t phys_addr(void *addr) + { + addr_t a = (addr_t)addr; + if (a < _base || a >= _base + SIZE) { + PERR("No DMA phys addr for %lx", a); + return 0; + } + return (a - _base) + _base_phys; + } + }; +} + +#endif /* _DMA_H_ */ diff --git a/dde_linux/src/drivers/usb/dummies.c b/dde_linux/src/drivers/usb/dummies.c index 0642876c5..237eee533 100644 --- a/dde_linux/src/drivers/usb/dummies.c +++ b/dde_linux/src/drivers/usb/dummies.c @@ -66,7 +66,7 @@ char *kasprintf(gfp_t gfp, const char *fmt, ...) { TRACE; return NULL; } int kstrtouint(const char *s, unsigned int base, unsigned int *res) { TRACE; return 0; } int sprintf(char *buf, const char *fmt, ...) { TRACE; return 0; } int sscanf(const char *b, const char *s, ...) { TRACE; return 0; } -int scnprintf(char *buf, size_t size, const char *fmt, ...) { TRACE; return 0; } +int scnprintf(char *buf, size_t size, const char *fmt, ...); int strict_strtoul(const char *s, unsigned int base, unsigned long *res) { TRACE; return 0; } long simple_strtoul(const char *cp, char **endp, unsigned int base) { TRACE; return 0; } @@ -100,7 +100,6 @@ int ffs(int x) { TRACE; return 0; } int memcmp(const void *dst, const void *src, size_t s) { TRACE; return 0; } char *strcat(char *dest, const char *src) { TRACE; return 0; } -int strcmp(const char *s1, const char *s2) { TRACE; return 0; } int strncmp(const char *cs, const char *ct, size_t count) { TRACE; return 0; } char *strncpy(char *dst, const char *src, size_t s) { TRACE; return NULL; } char *strchr(const char *s, int n) { TRACE; return NULL; } @@ -236,7 +235,7 @@ void __set_current_state(int state) { TRACE; } int signal_pending(struct task_struct *p) { TRACE; return 0; } void schedule(void) { TRACE; } void yield(void) { TRACE; } -void cpu_relax(void) { TRACE; } +void cpu_relax(void) { TRACE; udelay(1); } struct task_struct *current; @@ -321,7 +320,6 @@ bool device_can_wakeup(struct device *dev) { TRACE; return 0; } ********************/ int dev_set_name(struct device *dev, const char *name, ...) { TRACE; return 0; } -const char *dev_name(const struct device *dev) { TRACE; return NULL; } int dev_to_node(struct device *dev) { TRACE; return 0; } void set_dev_node(struct device *dev, int node) { TRACE; } @@ -523,7 +521,6 @@ void kunmap(struct page *page) { TRACE; } ** asm-generic/io.h ** **********************/ -void *ioremap(resource_size_t offset, unsigned long size) { TRACE; return NULL; } void iounmap(volatile void *addr) { TRACE; } void native_io_delay(void) { TRACE; } @@ -780,3 +777,19 @@ void scsi_host_put(struct Scsi_Host *shost) { TRACE; } struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) { TRACE; return 0; } +/******************************** + ** linux/regulator/consumer.h ** + ********************************/ +struct regulator; +int regulator_enable(struct regulator *r) { TRACE; return 0; } +int regulator_disable(struct regulator *r) { TRACE; return 0; } +void regulator_put(struct regulator *r) { TRACE; } +struct regulator *regulator_get(struct device *dev, const char *id) { TRACE; return 0; } + + +/******************************************* + ** arch/arm/plat-omap/include/plat/usb.h ** + *******************************************/ + +int omap_usbhs_enable(struct device *dev) { TRACE; return 0; } +void omap_usbhs_disable(struct device *dev) { TRACE; } diff --git a/dde_linux/src/drivers/usb/input/evdev.c b/dde_linux/src/drivers/usb/input/evdev.c index a96cb2923..161d3beb6 100644 --- a/dde_linux/src/drivers/usb/input/evdev.c +++ b/dde_linux/src/drivers/usb/input/evdev.c @@ -10,6 +10,13 @@ * the GNU General Public License version 2. */ +/* + * Copyright (C) 2009-2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + /* Linux */ #include diff --git a/dde_linux/src/drivers/usb/lx_emul.cc b/dde_linux/src/drivers/usb/lx_emul.cc index a8d4a2755..4b1eca730 100644 --- a/dde_linux/src/drivers/usb/lx_emul.cc +++ b/dde_linux/src/drivers/usb/lx_emul.cc @@ -20,6 +20,7 @@ #include /* Local includes */ +#include "dma.h" #include "routine.h" #include "signal.h" #include "lx_emul.h" @@ -198,15 +199,32 @@ int snprintf(char *buf, size_t size, const char *fmt, ...) } +int scnprintf(char *buf, size_t size, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + Genode::String_console sc(buf, size); + sc.vprintf(fmt, args); + va_end(args); + + return sc.len(); +} + +int strcmp(const char *s1, const char *s2) { return Genode::strcmp(s1, s2); } size_t strlen(const char *s) { return Genode::strlen(s); } size_t strlcat(char *dest, const char *src, size_t n) { size_t len = strlen(dest); - Genode::strncpy(dest + len, src, n); - dest[len + n] = 0; - return n; + + if (len >= n) + len = n - 1; + + memcpy(dest, src, len); + dest[len] = 0; + return len; } @@ -320,10 +338,10 @@ void kmem_cache_free(struct kmem_cache *cache, void *objp) ** asm-generic/io.h ** **********************/ -void *ioremap_wc(resource_size_t phys_addr, unsigned long size) +void *_ioremap(resource_size_t phys_addr, unsigned long size, int wc) { dde_kit_addr_t map_addr; - if (dde_kit_request_mem(phys_addr, size, 1, &map_addr)) { + if (dde_kit_request_mem(phys_addr, size, wc, &map_addr)) { PERR("Failed to request I/O memory: [%x,%lx)", phys_addr, phys_addr + size); return 0; } @@ -332,6 +350,18 @@ void *ioremap_wc(resource_size_t phys_addr, unsigned long size) } +void *ioremap_wc(resource_size_t phys_addr, unsigned long size) +{ + return _ioremap(phys_addr, size, 1); +} + + +void *ioremap(resource_size_t offset, unsigned long size) +{ + return _ioremap(offset, size, 0); +} + + /******************** ** linux/device.h ** ********************/ @@ -438,6 +468,7 @@ int dev_set_drvdata(struct device *dev, void *data) struct device *get_device(struct device *dev) { TRACE; return dev; } +const char *dev_name(const struct device *dev) { return dev->name; } long find_next_zero_bit_le(const void *addr, @@ -527,78 +558,9 @@ enum { JIFFIES_TICK_MS = 1000 / DDE_KIT_HZ }; unsigned long msecs_to_jiffies(const unsigned int m) { return m / JIFFIES_TICK_MS; } long time_after_eq(long a, long b) { return (a - b) >= 0; } -long time_after(long a, long b) { return (b - a) > 0; } +long time_after(long a, long b) { return (b - a) < 0; } -/********************* - ** linux/dmapool.h ** - *********************/ - -namespace Genode { - - /** - * Dma-pool manager - */ - class Dma - { - private: - - enum { SIZE = 1024 * 1024 }; - - addr_t _base; /* virt base of pool */ - addr_t _base_phys; /* phys base of pool */ - Allocator_avl _range; /* range allocator for pool */ - - Dma() : _range(env()->heap()) - { - Ram_dataspace_capability cap = env()->ram_session()->alloc(SIZE); - _base_phys = Dataspace_client(cap).phys_addr(); - _base = (addr_t)env()->rm_session()->attach(cap); - dde_kit_log(DEBUG_DMA, "New DMA range [%lx-%lx)", _base, _base + SIZE); - _range.add_range(_base, SIZE); - } - - public: - - static Dma* pool() - { - static Dma _p; - return &_p; - } - - /** - * Alloc 'size' bytes of DMA memory - */ - void *alloc(size_t size, int align = PAGE_SHIFT) - { - void *addr; - if (!_range.alloc_aligned(size, &addr, align)) { - PERR("DMA of %zu bytes allocation failed", size); - return 0; - } - - return addr; - } - - /** - * Free DMA memory - */ - void free(void *addr) { _range.free(addr); } - - /** - * Get phys for virt address - */ - addr_t phys_addr(void *addr) - { - addr_t a = (addr_t)addr; - if (a < _base || a >= _base + SIZE) { - PERR("No DMA phys addr for %lx", a); - return 0; - } - return (a - _base) + _base_phys; - } - }; -} struct dma_pool @@ -611,7 +573,7 @@ struct dma_pool struct dma_pool *dma_pool_create(const char *name, struct device *d, size_t size, size_t align, size_t alloc) { - dde_kit_log(DEBUG_DMA, "size: %zx align:%zx", size, align); + dde_kit_log(DEBUG_DMA, "size: %zx align:%zx %p", size, align, __builtin_return_address((0))); if (align & (align - 1)) return 0; @@ -633,12 +595,13 @@ void dma_pool_destroy(struct dma_pool *d) static void* _alloc(size_t size, int align, dma_addr_t *dma) { void *addr = Genode::Dma::pool()->alloc(size, align); - dde_kit_log(DEBUG_DMA, "addr: %p size %zx align: %d", addr, size, align); if (!addr) return 0; *dma = (dma_addr_t)Genode::Dma::pool()->phys_addr(addr); + dde_kit_log(DEBUG_DMA, "DMA pool alloc addr: %p size %zx align: %d, pysh: %lx", addr, size, align, *dma); + memset(addr, 0, size); return addr; } @@ -646,6 +609,8 @@ static void* _alloc(size_t size, int align, dma_addr_t *dma) void *dma_pool_alloc(struct dma_pool *d, gfp_t f, dma_addr_t *dma) { return _alloc(d->size, d->align, dma); +// return _alloc(0x1000, 12, dma); + } @@ -768,3 +733,13 @@ void *sg_virt(struct scatterlist *sg) struct page *page = (struct page *)sg->page_link; return (void *)((unsigned long)page->virt + sg->offset); } + + +/******************** + ** linux/ioport.h ** + ********************/ + +resource_size_t resource_size(const struct resource *res) +{ + return res->end - res->start + 1; +} diff --git a/dde_linux/src/drivers/usb/lx_emul.h b/dde_linux/src/drivers/usb/lx_emul.h index cecc5a4eb..897dbfc5e 100644 --- a/dde_linux/src/drivers/usb/lx_emul.h +++ b/dde_linux/src/drivers/usb/lx_emul.h @@ -37,15 +37,15 @@ extern "C" { #if VERBOSE_LX_EMUL -#define DEBUG_COMPLETION 1 +#define DEBUG_COMPLETION 0 #define DEBUG_DMA 0 -#define DEBUG_DRIVER 1 -#define DEBUG_IRQ 1 +#define DEBUG_DRIVER 0 +#define DEBUG_IRQ 0 #define DEBUG_KREF 0 -#define DEBUG_PCI 1 +#define DEBUG_PCI 0 #define DEBUG_SLAB 0 -#define DEBUG_TIMER 1 -#define DEBUG_THREAD 1 +#define DEBUG_TIMER 0 +#define DEBUG_THREAD 0 #else #define DEBUG_COMPLETION 0 #define DEBUG_DRIVER 0 @@ -661,10 +661,14 @@ int isprint(int); ******************/ #define __init +#define __initdata #define __devinit #define __devinitconst +#define __devexit #define __exit +#define __exit_p(x) x + #define subsys_initcall(fn) void subsys_##fn(void) { fn(); } @@ -679,6 +683,7 @@ int isprint(int); #define MODULE_LICENSE(x) #define MODULE_PARM_DESC(x, y) //#define MODULE_ALIAS_MISCDEV(x) /* needed by agp/backend.c */ +#define MODULE_ALIAS(x) #define THIS_MODULE 0 @@ -1239,7 +1244,12 @@ bool device_can_wakeup(struct device *dev); #define dev_WARN(dev, format, arg...) dde_kit_printf("dev_WARN: " format, ## arg) #define dev_err( dev, format, arg...) dde_kit_printf("dev_error: " format, ## arg) #define dev_notice(dev, format, arg...) dde_kit_printf("dev_notice: " format, ## arg) + +#if VERBOSE_LX_EMUL +#define dev_dbg(dev, format, arg...) dde_kit_printf("dev_dbg: " format, ## arg) +#else #define dev_dbg( dev, format, arg...) +#endif #define dev_printk(level, dev, format, arg...) \ dde_kit_printf("dev_printk: " format, ## arg) @@ -1284,12 +1294,16 @@ struct class char *(*devnode)(struct device *dev, mode_t *mode); }; +/* DEVICE */ struct device { + const char *name; struct device *parent; struct kobject kobj; const struct device_type *type; struct device_driver *driver; + void *platform_data; u64 *dma_mask; /* needed by usb/hcd.h */ + u64 coherent_dma_mask; /* omap driver */ struct dev_pm_info power; dev_t devt; const struct attribute_group **groups; @@ -1826,12 +1840,15 @@ static inline u32 inl_p(u32 port) { u32 ret = inl(port); native_io_delay(); retu ** linux/ioport.h ** ********************/ -#define IORESOURCE_IO 0x00000100 +#define IORESOURCE_IO 0x00000100 +#define IORESOURCE_MEM 0x00000200 +#define IORESOURCE_IRQ 0x00000400 struct resource { resource_size_t start; resource_size_t end; + const char *name; unsigned long flags; }; @@ -1843,6 +1860,7 @@ struct resource *request_mem_region(resource_size_t start, resource_size_t n, void release_region(resource_size_t start, resource_size_t n); void release_mem_region(resource_size_t start, resource_size_t n); +resource_size_t resource_size(const struct resource *res); /*********************** ** linux/interrupt.h ** @@ -2577,6 +2595,12 @@ struct scsi_driver }; +/********************************** + ** Platform specific defintions ** + *********************************/ +#include + + /********** ** misc ** **********/ diff --git a/dde_linux/src/drivers/usb/main.cc b/dde_linux/src/drivers/usb/main.cc index b1144d55f..c30cb1eb0 100644 --- a/dde_linux/src/drivers/usb/main.cc +++ b/dde_linux/src/drivers/usb/main.cc @@ -32,13 +32,11 @@ extern "C" { using namespace Genode; -extern "C" void subsys_usb_init(); +extern "C" int subsys_usb_init(); extern "C" void subsys_input_init(); -extern "C" void module_ehci_hcd_init(); extern "C" void module_evdev_init(); extern "C" void module_hid_init(); extern "C" void module_hid_init_core(); -extern "C" void module_uhci_hcd_init(); extern "C" void module_usb_mouse_init(); extern "C" void module_usb_kbd_init(); extern "C" void module_usb_stor_init(); @@ -74,10 +72,8 @@ static void init(bool hid, bool stor) /* * Host controller. * - * ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after */ - module_ehci_hcd_init(); - module_uhci_hcd_init(); + platform_hcd_init(); /* storage */ if (stor) diff --git a/dde_linux/src/drivers/usb/routine.h b/dde_linux/src/drivers/usb/routine.h index fc50b3fdd..10c8c7fac 100644 --- a/dde_linux/src/drivers/usb/routine.h +++ b/dde_linux/src/drivers/usb/routine.h @@ -22,6 +22,8 @@ extern "C" { #include } +#include + static const bool verbose = false; @@ -69,11 +71,7 @@ class Routine : public Genode::List::Element /* XXX move to platform code */ /* switch stack and call '_func(_arg)' */ - asm volatile ("movl %2, 0(%0);" - "movl %1, -0x4(%0);" - "movl %0, %%esp;" - "call *-4(%%esp);" - : : "r" (_stack + STACK_SIZE), "r" (_func), "r" (_arg)); + platform_execute((void *)(_stack + STACK_SIZE), (void *)_func, _arg); } /* restore old state */ diff --git a/dde_linux/src/drivers/usb/signal.h b/dde_linux/src/drivers/usb/signal.h index 9c766aa8e..1836f401c 100644 --- a/dde_linux/src/drivers/usb/signal.h +++ b/dde_linux/src/drivers/usb/signal.h @@ -31,6 +31,8 @@ class Driver_context : public Genode::Signal_context * Perform context operation */ virtual void handle() = 0; + + virtual char const *debug() = 0; }; diff --git a/dde_linux/src/drivers/usb/signal/event.cc b/dde_linux/src/drivers/usb/signal/event.cc index 960739a14..885c43349 100644 --- a/dde_linux/src/drivers/usb/signal/event.cc +++ b/dde_linux/src/drivers/usb/signal/event.cc @@ -43,6 +43,8 @@ class Event_context : public Driver_context void handle() { Routine::schedule_all(); } + + char const *debug() { return "Event_context"; } }; diff --git a/dde_linux/src/drivers/usb/signal/irq.cc b/dde_linux/src/drivers/usb/signal/irq.cc index c6c69b193..688dc208a 100644 --- a/dde_linux/src/drivers/usb/signal/irq.cc +++ b/dde_linux/src/drivers/usb/signal/irq.cc @@ -13,7 +13,7 @@ #include #include - +#include extern "C" { #include } @@ -93,18 +93,13 @@ class Irq_context : public Driver_context, /* report IRQ to all clients */ for (Irq_handler *h = _handler_list.first(); h; h = h->next()) { irqreturn_t rc; - do { - rc = h->handler(_irq, h->dev); - } - while (rc == IRQ_HANDLED); - dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u", _irq, rc); - if (rc == IRQ_HANDLED) { + if ((rc = h->handler(_irq, h->dev)) == IRQ_HANDLED) Routine::schedule_all(); - return; - } + dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u", _irq, rc); } } + const char *debug() { return "Irq_context"; } /** * Request an IRQ */ diff --git a/dde_linux/src/drivers/usb/signal/timer.cc b/dde_linux/src/drivers/usb/signal/timer.cc index 401d331fc..06baa4f24 100644 --- a/dde_linux/src/drivers/usb/signal/timer.cc +++ b/dde_linux/src/drivers/usb/signal/timer.cc @@ -59,6 +59,7 @@ class Timer_context : public Driver_context dde_kit_timer_schedule_absolute(_dde_timer, expires); } + char const *debug() { return "Timer_context"; } /** * Return true if timer is pending */ diff --git a/dde_linux/src/drivers/usb/storage/component.h b/dde_linux/src/drivers/usb/storage/component.h index 244b54fdb..d290b671e 100644 --- a/dde_linux/src/drivers/usb/storage/component.h +++ b/dde_linux/src/drivers/usb/storage/component.h @@ -73,6 +73,7 @@ namespace Block { ~Signal_dispatcher() { sig_rec->dissolve(this); } void handle() { (obj.*member)(); } + char const *debug() { return "Block_context"; } }; diff --git a/dde_linux/src/drivers/usb/storage/scsi.c b/dde_linux/src/drivers/usb/storage/scsi.c index 645545181..6d6c4ed42 100644 --- a/dde_linux/src/drivers/usb/storage/scsi.c +++ b/dde_linux/src/drivers/usb/storage/scsi.c @@ -27,6 +27,13 @@ * scsi_scan_host */ +/* + * Copyright (C) 2009-2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + #include #include "scsi.h" diff --git a/dde_linux/src/drivers/usb/target.mk b/dde_linux/src/drivers/usb/target.mk index 59642fda8..d11511c49 100644 --- a/dde_linux/src/drivers/usb/target.mk +++ b/dde_linux/src/drivers/usb/target.mk @@ -1,7 +1,6 @@ TARGET = usb_drv -REQUIRES = x86 32bit LIBS = cxx env dde_kit server libc-setjmp signal -SRC_CC = main.cc lx_emul.cc pci_driver.cc irq.cc timer.cc event.cc storage.cc \ +SRC_CC = main.cc lx_emul.cc irq.cc timer.cc event.cc storage.cc \ input_component.cc SRC_C = dummies.c scsi.c evdev.c @@ -18,7 +17,7 @@ INC_DIR += $(CONTRIB_DIR)/include INC_DIR += $(shell pwd) CC_OPT += -U__linux__ -D__KERNEL__ -CC_OPT += -DCONFIG_USB_DEVICEFS -DCONFIG_HOTPLUG -DCONFIG_PCI -DDEBUG +CC_OPT += -DCONFIG_USB_DEVICEFS -DCONFIG_HOTPLUG -DDEBUG CC_WARN = -Wall -Wno-unused-variable -Wno-uninitialized \ -Wno-unused-function \ @@ -37,8 +36,7 @@ SRC_C += $(addprefix usb/core/,$(notdir $(wildcard $(USB_DIR)/core/*.c))) SRC_C += usb/usb-common.c # USB host-controller driver -#SRC_C += $(addprefix usb/host/,uhci-hcd.c pci-quirks.c ehci-hcd.c ohci-hcd.c) -SRC_C += $(addprefix usb/host/,pci-quirks.c uhci-hcd.c ehci-hcd.c) +SRC_C += $(addprefix usb/host/, ehci-hcd.c) # USB hid SRC_C += $(addprefix hid/usbhid/,hid-core.c hid-quirks.c usbmouse.c usbkbd.c) @@ -61,13 +59,48 @@ GEN_INCLUDES := $(shell grep -rh "^\#include .*\/" $(CONTRIB_DIR) |\ # # Filter out some black-listed headers # -NO_GEN_INCLUDES := ../../scsi/sd.h + + +######################## +## Platform specifics ## +######################## + +SUPPORTED = x86_32 platform_panda + +# +# x86_32 +# +ifeq ($(filter-out $(SPECS),x86_32),) +INC_DIR += $(PRG_DIR)/x86_32 +CC_OPT += -DCONFIG_PCI +SRC_C += $(addprefix usb/host/,pci-quirks.c uhci-hcd.c) +SRC_CC += pci_driver.cc + +# +# Panda board +# +else ifeq ($(filter-out $(SPECS),platform_panda),) +CC_OPT += -DCONFIG_USB_EHCI_HCD_OMAP -DCONFIG_USB_EHCI_TT_NEWSCHED -DVERBOSE_DEBUG +INC_DIR += $(PRG_DIR)/arm +INC_DIR += $(CONTRIB_DIR)/arch/arm/plat-omap/include +SRC_C += platform_device.c +SRC_CC += platform.cc +#SRC_C += $(CONTRIB_DIR)/arch/arm/mach-omap2/usb-host.c +#SRC_C += $(DRIVERS_DIR)/mfd/omap-usb-host.c +vpath %.c $(PRG_DIR)/arm/platform +vpath %.cc $(PRG_DIR)/arm/platform +# +# Unsupported +# +else +$(error Skip USB because it requires one of the following: $(SUPPORTED)) +endif # # Filter out original Linux headers that exist in the contrib directory # NO_GEN_INCLUDES := $(shell cd $(CONTRIB_DIR)/include; find -name "*.h" | sed "s/.\///") -GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES)) +GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES)) # # Make sure to create the header symlinks prior building diff --git a/dde_linux/src/drivers/usb/x86_32/platform/lx_emul.h b/dde_linux/src/drivers/usb/x86_32/platform/lx_emul.h new file mode 100644 index 000000000..42c01e309 --- /dev/null +++ b/dde_linux/src/drivers/usb/x86_32/platform/lx_emul.h @@ -0,0 +1,18 @@ +/* + * \brief Platform specific part of the Linux API emulation + * \author Sebastian Sumpf + * \date 2012-06-18 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _X86_32__PLATFORM__LX_EMUL_ +#define _X86_32__PLATFORM__LX_EMUL_ + + +#endif /* _X86_32__PLATFORM__LX_EMUL_ */ diff --git a/dde_linux/src/drivers/usb/x86_32/platform/platform.h b/dde_linux/src/drivers/usb/x86_32/platform/platform.h new file mode 100644 index 000000000..ce4a21bd7 --- /dev/null +++ b/dde_linux/src/drivers/usb/x86_32/platform/platform.h @@ -0,0 +1,38 @@ +/** + * \brief Platform specific code + * \author Sebastian Sumpf + * \date 2012-06-10 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _X86_32__PLATFORM_H_ +#define _X86_32__PLATFORM_H_ + +static inline +void platform_execute(void *sp, void *func, void *arg) +{ + asm volatile ("movl %2, 0(%0);" + "movl %1, -0x4(%0);" + "movl %0, %%esp;" + "call *-4(%%esp);" + : : "r" (sp), "r" (func), "r" (arg)); +} + +extern "C" void module_ehci_hcd_init(); +extern "C" void module_uhci_hcd_init(); + +static inline void platform_hcd_init(void) +{ + + /* ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after */ + module_ehci_hcd_init(); + module_uhci_hcd_init(); +} + +#endif /* _X86_32__PLATFORM_H_ */ diff --git a/libports/lib/mk/arm/libc-setjmp.mk b/libports/lib/mk/arm/libc-setjmp.mk index 15277c2eb..dfe0944d4 100644 --- a/libports/lib/mk/arm/libc-setjmp.mk +++ b/libports/lib/mk/arm/libc-setjmp.mk @@ -1,6 +1,11 @@ LIBC_GEN_ARM_DIR = $(LIBC_DIR)/libc/arm/gen -SRC_S = _setjmp.S setjmp.S +SRC_S = _setjmp.S setjmp.S + +# +# Remove 'longjmperror' call +# +CC_OPT += -D_STANDALONE include $(REP_DIR)/lib/mk/libc-common.inc