Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Autres questions


Index du Forum » Autres questions » le DMA controller sur g35 ?
Milang Hors ligne Membre Points: 488 Défis: 2 Message

le DMA controller sur g35 ?

Posté le 18/07/2019 18:57

J'ai enendu parler du DMA(direct memory access) et de son utilisation pour augmenter les perfs de la g90 pour l'affichage.

Je me suis logiquement posé les questions suivantes :

1. Le DMA existe-t-il sur les modèles monochromes ?
2. Si oui, est-il possible de l'exploiter pour effacer une certaine zone de la RAM ?
3. si oui et oui, comment l'exploiter ?

En fait j'aimerais pouvoir l'utiliser dans mon moteur 3d pour effacer le zbuffer pendant que le processeur calcule les coordonnées de points après rotation.


Milang Hors ligne Membre Points: 488 Défis: 2 Message

Citer : Posté le 18/07/2019 22:09 | #


Merci !
Allez hop et un topic résolu en un soir !
Lephenixnoir Hors ligne Administrateur Points: 24670 Défis: 170 Message

Citer : Posté le 18/07/2019 22:10 | #


Bien joué ! Si ton code est à peu près clean tu peux soumettre une pull request...
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Milang Hors ligne Membre Points: 488 Défis: 2 Message

Citer : Posté le 18/07/2019 22:30 | #


Donc au niveau du code
Donc rajouter de lasm pour prendre en compte le channel 1 et je modifie un peu ta fonction pour choisir dynamiquement le bon channel, c'est ça ?
Lephenixnoir Hors ligne Administrateur Points: 24670 Défis: 170 Message

Citer : Posté le 18/07/2019 22:31 | #


Oui, c'est ça ! Si possible dans dma_setup() ne pas c/c le code de configuration mais utiliser un pointeur.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Milang Hors ligne Membre Points: 488 Défis: 2 Message

Citer : Posté le 18/07/2019 22:36 | #


Dans les arguments ?
Lephenixnoir Hors ligne Administrateur Points: 24670 Défis: 170 Message

Citer : Posté le 18/07/2019 22:38 | #


Hmm, je dirais prendre le numéro de channel en argument (0/1/2) et ensuite calculer le pointeur (&DMA.DMA{0,1,2}) à l'intérieur de la fonction.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Milang Hors ligne Membre Points: 488 Défis: 2 Message

Citer : Posté le 18/07/2019 22:46 | #


Au niveau de init, il faut mettre quelles adresses pour gint_int_handler
Lephenixnoir Hors ligne Administrateur Points: 24670 Défis: 170 Message

Citer : Posté le 18/07/2019 22:49 | #


0x800 pour le channel 0, 0x820 pour le 1, 0x840 pour le 2 et il semble y en avoir un dernier, qui serait 0x860 à tester.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Milang Hors ligne Membre Points: 488 Défis: 2 Message

Citer : Posté le 18/07/2019 22:49 | #


Allez hop je t'écrirai aussi dma_memset et dma_memcpy, avec les parametres standards

Ajouté le 19/07/2019 à 11:22 :
du coup du coté de inth.s c'est bon :
/*
**  gint:dma:inth - Interrupt handler for the DMA
**  An easy one, just clears some flags and marks all transfers as finished.
*/

.global _inth_dma_dma0
.section .gint.blocks, "ax"
.align 4

/* DMA TRANSFER ENDED INTERRUPT HANDLER - BYTES */

_inth_dma_dma0:
    /* Clear the TE flag and DMA Enable in CHCR */
    mov.l    1f, r1
    mov.l    @r1, r0
    mov    #-4, r2
    and    r2, r0
    mov.l    r0, @r1

    /* Clear the AE and NMIF flags in OR, and cut the master switch */
    add    #0x34, r1
    mov.w    @r1, r0
    shlr8    r0
    shll8    r0
    mov.w    r0, @r1

    rte
    nop
    nop
    nop



.global _inth_dma_dma1
.section .gint.blocks, "ax"
.align 4

_inth_dma_dma1:
    /* Clear the TE flag and DMA Enable in CHCR */
    mov.l    2f, r1
    mov.l    @r1, r0
    mov    #-4, r2
    and    r2, r0
    mov.l    r0, @r1

    /* Clear the AE and NMIF flags in OR, and cut the master switch */
    add    #0x34, r1
    mov.w    @r1, r0
    shlr8    r0
    shll8    r0
    mov.w    r0, @r1

    rte
    nop
    nop
    nop



.global _inth_dma_dma2
.section .gint.blocks, "ax"
.align 4

_inth_dma_dma2:
    /* Clear the TE flag and DMA Enable in CHCR */
    mov.l    3f, r1
    mov.l    @r1, r0
    mov    #-4, r2
    and    r2, r0
    mov.l    r0, @r1

    /* Clear the AE and NMIF flags in OR, and cut the master switch */
    add    #0x34, r1
    mov.w    @r1, r0
    shlr8    r0
    shll8    r0
    mov.w    r0, @r1

    rte
    nop
    nop
    nop


1:    .long 0xfe00802c    /* CHCR0 - OR is 0x34 bytes after this */
2:    .long 0xfe00803c
3:    .long 0xfe00804c


Ajouté le 19/07/2019 à 11:31 :
mais par contre pour calculer automatiquement le pointeur j'ai des doutes :
je le met de type void* ?
Pour calculer DMA.DMAx ça c'est ok :
void* UsedDMA=0xFE008020 + 2*x;

Mais du coup, pour l'exploiter, est-ce que j'ai le droit de faire par exemple
UsedDMA.CHCR.DE = 0; // Comment le compilateur peut il savoir de quoi je parle ?
au lieu de
DMA.DMA0.CHCR.DE = 0;
C'est en fait ça qui me fait douter sur le choix du (void*)
est-ce que il faut modifier les fonctions en "ctx_" ? Je n'ai pas vraiment compris à quoi elles servent


Enfin, pour ce qui est du memset et memcpy, pour l'instant je ne sais pas si on peut écrire octet par octet avec le DMA, et j'en ai pas particulièrement besoin en fait
Lephenixnoir Hors ligne Administrateur Points: 24670 Défis: 170 Message

Citer : Posté le 19/07/2019 12:47 | #


C'est pas mal, merci ! Queques remarques sur l'assembleur. Ces deux lignes ne sont pas nécessaires :

.section .gint.blocks, "ax"
.align 4

puisque la section est déjà définie et l'alignment est préservé au-dessus (au contraire si le bloc au-dessus fait pas un multiple de 4 en taille je préfère que ça plante avec une erreur de compil' parce que c'est pas normal !).

Pour la suite, si tu veux accéder au registre OR, c'est 0x34 octets avec CHCR0, mais du coup par rapport à CHCR1 c'est 0x24 et par rapport à CHCR2 c'est 0x14. Couper le master switch arrête tous les DMAs en même temps donc c'est probablement quelque chose à modifier mais je m'occuperai de la doc pour trouver comment...

Comme ces gestionnaires d'interruption sont tous des blocs de taille fixe, c'est bien qu'ils soient "free-standing". En particulier les données doivent être à la fin des blocs parce que le repositionnement va casser les références indirectes. Les adresses des CHCR devraient donc être à la fin de chaque bloc ; tu peux aussi vérifier que chaque gestionnaire doit faire exactement 32 octets.

Milang a écrit :
Pour calculer DMA.DMAx ça c'est ok :
void* UsedDMA=0xFE008020 + 2*x;

Le plus clean c'est de compter en octets, auquel cas ce serait :
sh7305_dma_channel_t *UsedDMA = (void *)(0xfe008020 + 16 * x);

Note que tu peux aussi caster 0xfe008020 en void* puis calculer dessus puisque dans GCC l'arithmétique de void* est par octet. Le cast est important sinon tu ne peux pas accéder aux données ensuite !

Mais du coup, pour l'exploiter, est-ce que j'ai le droit de faire par exemple
UsedDMA.CHCR.DE = 0; // Comment le compilateur peut il savoir de quoi je parle ?

Une fois que tu as casté c'est bon, à la notation près :
UsedDMA->CHCR.DE = 0;

J'ai remarqué que dans mon header <gint/mpu/dma.h> j'ai documenté 6 channels différents en fait. S'il en existe bien 6 alors je paramétrerai le code et les interrupt handlers pour éviter d'avoir 6 fois la même chose, ce qui serait dommage.

est-ce que il faut modifier les fonctions en "ctx_" ? Je n'ai pas vraiment compris à quoi elles servent

Ces fonctions servent à sauvegarder l'état complet du DMA dans un objet de type ctx_t (contexte) puis à le restaurer à la fin. C'est parce que gint prend le contrôle du matériel mais doit ultimement le rendre au système d'exploitation, et donc restaurer tous les paramètres à leur état initial. Comme le driver modifie maintenant le DMA1/2, il faut aussi les sauvegarder - donc rajouter des éléments dans ctx_t et copier plus de choses, avec une boucle certainement. Si tu as un doute je le ferai.

Enfin, pour ce qui est du memset et memcpy, pour l'instant je ne sais pas si on peut écrire octet par octet avec le DMA, et j'en ai pas particulièrement besoin en fait

Tu peux mais c'est pas intéressant ! Laisse par blocs de 32 octets, on documentera que ces fonctions ne sont que pour des blocs 32-alignés avec des tailles multiples de 32 et puis c'est tout.

Merci encore pour ton aide !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Milang Hors ligne Membre Points: 488 Défis: 2 Message

Citer : Posté le 19/07/2019 14:05 | #


A quoi correspond le premier argument de gint_intlevel(int,int) ?
Lephenixnoir Hors ligne Administrateur Points: 24670 Défis: 170 Message

Citer : Posté le 19/07/2019 14:09 | #


C'est le numéro d'une position dans les registres IPR* du contrôleur d'interruption. Regarde page 364 de la doc du SH7724 : il suffit de compter de haut en bas et de gauche à droite en partant de 0. Par exemple IPRB & 0x00f0 c'est 6 (DMAC1A sur SH7724 ; vois <gint/mpu/intc.h> pour une liste plus proche du SH7305).

Je vais les nommer parce que c'est trop casse-pieds de suivre les numéros.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Milang Hors ligne Membre Points: 488 Défis: 2 Message

Citer : Posté le 19/07/2019 14:23 | #


je ne comprends toujours pas quelle est la valeur que je dois mettre
Lephenixnoir Hors ligne Administrateur Points: 24670 Défis: 170 Message

Citer : Posté le 19/07/2019 14:40 | #


En fait la réponse est "rien" parce que l'interruption que le gint_intlevel() actuel active concerne l'ensemble du DMA donc tous les channels à la fois.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 112 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd