# HG changeset patch # User Paul Boddie # Date 1708725155 -3600 # Node ID 810dc31a547f806325edfa689c92c9e22e776f07 # Parent 200859fe60d963f5c0f26d3ff027390e9878e87d Bind IRQs in the current thread instead of the main thread. This helps to avoid main thread IPC conflicts later on. diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/dma/src/jz4730.cc --- a/pkg/devices/lib/dma/src/jz4730.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/dma/src/jz4730.cc Fri Feb 23 22:52:35 2024 +0100 @@ -1,7 +1,7 @@ /* * DMA support for the JZ4730. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,11 +22,14 @@ #include #include -#include #include #include +#include #include +#include +#include + #include @@ -336,6 +339,9 @@ bool Dma_jz4730_channel::wait_for_irq() { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + return !l4_error(l4_irq_receive(_irq, L4_IPC_NEVER)) && _chip->have_interrupt(_channel); } @@ -345,6 +351,9 @@ bool Dma_jz4730_channel::wait_for_irq(unsigned int timeout) { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + return !l4_error(l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(timeout)))) && _chip->have_interrupt(_channel); } diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/dma/src/jz4780.cc --- a/pkg/devices/lib/dma/src/jz4780.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/dma/src/jz4780.cc Fri Feb 23 22:52:35 2024 +0100 @@ -24,11 +24,14 @@ #include #include -#include #include #include +#include #include +#include +#include + #include @@ -394,7 +397,12 @@ Dma_jz4780_channel::wait_for_irq() { if (l4_is_valid_cap(_irq)) + { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + return !l4_error(l4_irq_receive(_irq, L4_IPC_NEVER)) && _chip->have_interrupt(_channel); + } else return true; } @@ -406,7 +414,12 @@ Dma_jz4780_channel::wait_for_irq(unsigned int timeout) { if (l4_is_valid_cap(_irq)) + { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + return !l4_error(l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(timeout)))) && _chip->have_interrupt(_channel); + } else return true; } diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/dma/src/x1600.cc --- a/pkg/devices/lib/dma/src/x1600.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/dma/src/x1600.cc Fri Feb 23 22:52:35 2024 +0100 @@ -22,11 +22,14 @@ #include #include -#include #include #include +#include #include +#include +#include + #include @@ -348,6 +351,9 @@ bool Dma_x1600_channel::wait_for_irq() { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + return !l4_error(l4_irq_receive(_irq, L4_IPC_NEVER)) && _chip->have_interrupt(_channel); } @@ -357,6 +363,9 @@ bool Dma_x1600_channel::wait_for_irq(unsigned int timeout) { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + return !l4_error(l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(timeout)))) && _chip->have_interrupt(_channel); } diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/hdmi/src/jz4780.cc --- a/pkg/devices/lib/hdmi/src/jz4780.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/hdmi/src/jz4780.cc Fri Feb 23 22:52:35 2024 +0100 @@ -51,8 +51,12 @@ #include #include +#include #include +#include +#include + /* I2C pins: @@ -759,6 +763,11 @@ uint8_t int_status; l4_msgtag_t tag; + err = l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0)); + + if (err) + return err; + do { tag = l4_irq_receive(_irq, L4_IPC_NEVER); diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc --- a/pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/lcd/src/jz4740/lcd-jz4740.cc Fri Feb 23 22:52:35 2024 +0100 @@ -3,7 +3,7 @@ * * Copyright (C) Xiangfu Liu * Copyright (C) 2015, 2016, 2017, 2018, - * 2020 Paul Boddie + * 2020, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -24,9 +24,13 @@ #include #include #include +#include #include #include +#include +#include + #include "lcd-jz4740.h" #include "lcd-jz4740-config.h" #include "lcd-jz4740-regs.h" @@ -626,6 +630,11 @@ _regs[Lcd_status] = _regs[Lcd_status] & ~(_status_irq()); + long err = l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0)); + + if (err) + return err; + // Wait for a condition. tag = l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(2000000))); diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/msc/include/msc-common.h --- a/pkg/devices/lib/msc/include/msc-common.h Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/msc/include/msc-common.h Fri Feb 23 22:52:35 2024 +0100 @@ -130,6 +130,9 @@ uint8_t num_cards(); + uint32_t read(uint8_t card, struct dma_region *region, + uint32_t address, uint32_t count); + uint32_t read_blocks(uint8_t card, struct dma_region *region, uint32_t block_address, uint32_t block_count); }; diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/msc/include/msc-jz4780.h --- a/pkg/devices/lib/msc/include/msc-jz4780.h Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/msc/include/msc-jz4780.h Fri Feb 23 22:52:35 2024 +0100 @@ -97,6 +97,10 @@ void jz4780_msc_enable(void *msc_channel); +uint32_t jz4780_msc_read(void *msc_channel, uint8_t card, + struct dma_region *region, + uint32_t address, uint32_t count); + uint32_t jz4780_msc_read_blocks(void *msc_channel, uint8_t card, struct dma_region *region, uint32_t block_address, uint32_t block_count); diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/msc/include/msc-x1600.h --- a/pkg/devices/lib/msc/include/msc-x1600.h Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/msc/include/msc-x1600.h Fri Feb 23 22:52:35 2024 +0100 @@ -99,6 +99,10 @@ void x1600_msc_enable(void *msc_channel); +uint32_t x1600_msc_read(void *msc_channel, uint8_t card, + struct dma_region *region, + uint32_t address, uint32_t count); + uint32_t x1600_msc_read_blocks(void *msc_channel, uint8_t card, struct dma_region *region, uint32_t block_address, uint32_t block_count); diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/msc/src/common.cc --- a/pkg/devices/lib/msc/src/common.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/msc/src/common.cc Fri Feb 23 22:52:35 2024 +0100 @@ -21,8 +21,12 @@ #include #include +#include #include +#include +#include + #include #include @@ -445,6 +449,9 @@ bool Msc_channel::wait_for_irq(uint32_t flags) { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + return !l4_error(l4_irq_receive(_irq, L4_IPC_NEVER)) && (_regs[Msc_interrupt_flag] & flags); } @@ -455,6 +462,9 @@ bool Msc_channel::wait_for_irq(uint32_t flags, unsigned int timeout) { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + return !l4_error(l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(timeout)))) && (_regs[Msc_interrupt_flag] & flags); @@ -798,6 +808,26 @@ return to_transfer; } +// Read data from the indicated card into a memory region. + +uint32_t +Msc_channel::read(uint8_t card, struct dma_region *region, + uint32_t address, uint32_t count) +{ + uint32_t block_size = 1 << _cards[card].csd.read_blocklen; + + // Obtain the block address from the byte address and the number of blocks + // from the byte count. + + // NOTE: Rejecting addresses and counts that are not multiples of the block + // NOTE: size. Should produce an error. + + if ((address % block_size) || (count % block_size)) + return 0; + + return read_blocks(card, region, address / block_size, count / block_size); +} + // Read blocks from the indicated card into a memory region. uint32_t diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/msc/src/jz4780.cc --- a/pkg/devices/lib/msc/src/jz4780.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/msc/src/jz4780.cc Fri Feb 23 22:52:35 2024 +0100 @@ -120,6 +120,14 @@ static_cast(msc_channel)->enable(); } +uint32_t jz4780_msc_read(void *msc_channel, uint8_t card, + struct dma_region *region, + uint32_t address, uint32_t count) +{ + return static_cast(msc_channel)->read(card, region, + address, count); +} + uint32_t jz4780_msc_read_blocks(void *msc_channel, uint8_t card, struct dma_region *region, uint32_t block_address, uint32_t block_count) diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/msc/src/x1600.cc --- a/pkg/devices/lib/msc/src/x1600.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/msc/src/x1600.cc Fri Feb 23 22:52:35 2024 +0100 @@ -137,6 +137,14 @@ static_cast(msc_channel)->enable(); } +uint32_t x1600_msc_read(void *msc_channel, uint8_t card, + struct dma_region *region, + uint32_t address, uint32_t count) +{ + return static_cast(msc_channel)->read(card, region, + address, count); +} + uint32_t x1600_msc_read_blocks(void *msc_channel, uint8_t card, struct dma_region *region, uint32_t block_address, uint32_t block_count) diff -r 200859fe60d9 -r 810dc31a547f pkg/devices/lib/tcu/src/common.cc --- a/pkg/devices/lib/tcu/src/common.cc Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/devices/lib/tcu/src/common.cc Fri Feb 23 22:52:35 2024 +0100 @@ -22,8 +22,12 @@ #include #include #include +#include #include +#include +#include + #include // log2 #include "tcu-common.h" @@ -268,7 +272,10 @@ bool Tcu_channel::wait_for_irq() -{ +{ + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + bool irq = !l4_error(l4_irq_receive(_irq, L4_IPC_NEVER)) && have_interrupt(); if (irq) @@ -283,6 +290,9 @@ bool Tcu_channel::wait_for_irq(unsigned int timeout) { + if (l4_error(l4_rcv_ep_bind_thread(_irq, pthread_l4_cap(pthread_self()), 0))) + return false; + bool irq = !l4_error(l4_irq_receive(_irq, l4_timeout(L4_IPC_TIMEOUT_NEVER, l4util_micros2l4to(timeout)))) && have_interrupt(); if (irq) diff -r 200859fe60d9 -r 810dc31a547f pkg/landfall-examples/hw_info/hw_info.c --- a/pkg/landfall-examples/hw_info/hw_info.c Wed Feb 21 00:33:55 2024 +0100 +++ b/pkg/landfall-examples/hw_info/hw_info.c Fri Feb 23 22:52:35 2024 +0100 @@ -100,16 +100,6 @@ return 1; } - /* Attach ourselves to the interrupt handler. */ - - err = l4_error(l4_rcv_ep_bind_thread(irq, l4re_env()->main_thread, num)); - - if (err) - { - printf("Could not attach to IRQs: %ld\n", err); - return 1; - } - return 0; }