Dostęp do danych sterownika jądra z programu obsługi przerwań FIQ nie działa

W przerwaniach FIQ ARM mamy kilka rejestrów zarezerwowanych tylko do użytku FIQ, a są to przydatne sposoby „zapisywania stanu” na przykład przesyłania danych między połączeniami FIQ.

Obecnie wyzwalam niektóreGPIO pinów z FIQ i działa zgodnie z oczekiwaniami. Podczas konfigurowania modułu obsługi FIQ przekazuję wskaźniki do rejestrów danych, które zostały zmapowane za pomocą ioremap. Kod roboczy wygląda tak:

//Driver initialization:
static char* dout0;
static char* din0;
...
static int driver_probe(struct platform_device *pdev) 
{
struct pt_regs regs;
...
dout0 = ioremap(HW_PINCTRL_DOUT0, 0xffff);
din0  = ioremap(HW_PINCTRL_DIN0, 0xffff);
...
regs.ARM_r8 = (long) dout0;
regs.ARM_r9 = (long) din0;
set_fiq_regs(&regs);
...

//In the FIQ handler:
LDR r12, [r8]
ORR r12, r12, #0x20 /* set pin 5 high in dout0 register */
STR r12, [r8]

Powyższy kod działa zgodnie z oczekiwaniamipin 5 jest ustawiony wysoko po wykonaniu procedury FIQ.

W przypadku bardziej skomplikowanych operacji chcę przygotować strukturę, która będzie przechowywać wskaźniki danych i inne dane związane z przetwarzaniem, w tym więcej mapowań do różnych rejestrów - i przekazać to do obsługi FIQ. Ale coś już nie tak się dzieje podczas migracji powyższego kodu do tego.

Zmodyfikowałem powyższy kod, aby wyglądał tak

//In Driver:
struct fiq_processing {
    char* din0;
    char* dout0;
};

static fiq_processing * pdata; //Pointer to our processing data structure

...
static int driver_probe(struct platform_device *pdev) 
{
struct pt_regs regs;
pdata = kmalloc(sizeof(*pdata), GFP_KERNEL); //Allocate memory for struct
printk("Size of the data struct %d \n", sizeof(*pdata)); //I get "8" as the size
...
pdata->din0  = ioremap(HW_PINCTRL_DIN0, 0xffff);
pdata->dout0 = ioremap(HW_PINCTRL_DOUT0, 0xffff);
...
regs.ARM_r8 = (long) pdata;
set_fiq_regs(&regs);
...

//In the FIQ handler:
#define OFFSET_DIN0 0x0 
#define OFFSET_DOUT0 0x4 //We know size is 8, so offset for dout is half from that
...
LDR r12, [r8, #OFFSET_DOUT0]
ORR r12, r12, #0x20 /* set pin 5 high in dout0 register */
STR r12, [r8, #OFFSET_DOUT0] /* This will do nothing ? */

Po przydzieleniu pamięci dla struktury i zmapowaniu wskaźników rejestru przekazuję adres struktury pdata do modułu obsługi FIQ. W module obsługi FIQ mam offset dladin0 idout0, o którym myślałem, że będzie0x0 i0x4 odpowiednio (odjęte od wielkości struktury 8).

Ale z jakiegoś powodu, teraz mój FIQ nie jest już w stanie ustawić wysokiego poziomu wyjścia - nie mogę zrozumieć, co robię źle tutaj. LUB to połączenieSTR r12, [r8, #OFFSET_DOUT0] niepoprawny? Rzeczywisty FIQ jest nieco dłuższy (odczytuje stan wejściowy, a wejście z niego tworzy pewne warunki), ale nawet podstawowy zestaw bitów wydaje się teraz zawodzić.

questionAnswers(1)

yourAnswerToTheQuestion