Il giorno venerdì 24 febbraio 2017 00:57:54 UTC+1, Ralf Ramsauer ha scritto:
> On 02/23/2017 01:28 PM, [email protected] wrote:
> > Il giorno giovedì 23 febbraio 2017 20:39:39 UTC+1, Ralf Ramsauer ha scritto:
> >> On 02/23/2017 04:15 AM, [email protected] wrote:
> >>> Il giorno mercoledì 22 febbraio 2017 14:48:09 UTC+1, Errico Guidieri ha
> >>> scritto:
> >>>> Dear guys,
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> I need to route a specific interrupt to my non-root cell (based
> >>>> on jetson-demo.cell) on a ARM64 device (TegraTX1), and I have the
> >>>> following questions.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> 1. I've seen in gic-demo that interrupt 27, that seems to be
> >>>> tied to ARMv8 CPU internal Timer, even thought this is not
> >>>> reporterd in TegraX1 RFM AFAICS, is available to the non-root cell
> >>>> even without providing any specific IRQ configuration in the
> >>>> non-root cell configuration (jetson-demo.c cell). However, if I
> >>>> try to enable a different IRQ, the system hangs (I would have
> >>>> expected an exception TBH). Is there any reason why the timer
> >>>> interrupt behaves differently than the others ?
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> 2. How do I configure the non-root cell to route a specific IRQ
> >>>> to my cell I guess that I've to use the jailhouse_irqchip
> >>>> structure and the .irqchips field, providing the right address and
> >>>> bitmask. However, I can't figure out these values.
> >>>>
> >>>> I'm confused since I noted that in the FreeRTOS cell the GIC
> >>>> address differs between the root cell and the non-root cell, and I
> >>>> can't figure out the reason.
> >>>>
> >>>> Even the bitmask value is not clear since the bit set by the
> >>>> FreeRTOS cell is IRQNO - 32: is it this a constant requiremet for
> >>>> GIC? In other words in any implementation of ARM that use GIC am I
> >>>> supposed to subtract 32 from the number I find in the Hardware
> >>>> Reference Manual?
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> 3. I also noted that the FreeRTOS porting has re-implemented
> >>>> the inmate library from scratch and it does not link against the
> >>>> usual Jailhouse library. Since their implementation provide
> >>>> basically the same services with a few small additions (e.g.,
> >>>> priorities handling for IRQs), I wonder the reason why they have
> >>>> chosen to use a different implementation rather than merging these
> >>>> additions to the mainline project.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> 4. This question is more a curiosity. In header.S the irq
> >>>> vector entries do not save and restore the scratch/volatile
> >>>> registers. IMHO this seems to not match the ARMv8 ABI and could
> >>>> even bring to abnormal behavior in some circumstances. Is it
> >>>> correct or am I wrong ?
> >>>>
> >>>> original ARM porting (32 bit) used GCC
> >>>> __attribute__((interrupt("IRQ")))
> >>>> for vector_irq function, but this strategy is no more available on
> >>>> ARM64 (I don't know why this features has not been added for ARMv8
> >>>> version of the GCC too).
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> Many thanks and best regards,
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>> Errico Guidieri
> >>>>
> >>>>
> >>>>
> >>>> --
> >>>>
> >>>> Errico Gudieri
> >>>> Senior Embedded Engineer
> >>>> Phone: +39.050.99.11.224 (122)
> >>>> E-mail: [email protected]
> >>>>
> >>>> EVIDENCE srl
> >>>> Via Carducci 56 - Loc. Ghezzano - 56010 - S. Giuliano Terme - Pisa -
> >>>> Italy
> >>>> Phone: +39.050.99.11.122 - 224
> >>>> Fax: +39.050.99.10.812 - 855
> >>>
> >>> Thank You Andrea,
> >>>
> >>> with yours directions I understood better the jailhouse configuration and
> >>> I could make some step forward, but still I cannot make the interrupt in
> >>> my cell.
> >>>
> >>> The interrupt that I need is GPIO-1. For what I understood by TegraX1 the
> >>> documentation:
> >>> 1) its global id is 32
> >>> 2) it belongs to Secondary Interrupt Controller (SEC_ICTLR)
> >>>
> >>> So these basically are the changes that I have dono on jetson-demo.c cell:
> >>>
> >>>
> >>> struct {
> >>> ...
> >>> struct jailhouse_irqchip irqchips[1];
> >>> } __attribute__((packed)) config = {
> >>> .cell = {
> >>> ...
> >>> /* The following was initially Forgot :) */
> >>> .num_irqchips = ARRAY_SIZE(config.irqchips),
> >>> },
> >>>
> >>> ...
> >>>
> >> Hi Errico,
> >>> .mem_regions = {
> >>> /* GPIOs until exception vectors */ {
> >>> .phys_start = 0x6000d000,
> >>> .virt_start = 0x6000d000,
> >>> .size = 0x2000,
> >> Why 0x2000? GPIO region is 0x1000. Exception vectors start at 0x6000f000
> >> and GPIO ends at 0x6000d7ff, but that's not the point...
> > You are right I just copied the mem_regionfrom the jetson-tx1 cell that I
> > have in a localrepository, but seems to be not aligned to the official one
> >
> >>> .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
> >>> JAILHOUSE_MEM_IO | JAILHOUSE_MEM_ROOTSHARED,
> >>> },
> >> uh - rootshared. Only share the memory with you root cell if there's no
> >> way out, and if you are 100% sure that the root cell won't undo or
> >> overwrite settings that you just set in your non-root cell.
> >>
> >> Try to disable ROOTSHARED, and only activate it as last resort.
> >>
> > I could shrink the region to the only GPIO-1* (I'm using only the pins of
> > SPI1), but still I need to leave Linux access GPIO-1 to the pins that are
> > not on header J21, or not?
OK I have made the things works, the problem was that I was trying to enable
irqn=32 calling gic_enable_irq(32) instead I needed to call
gic_enable_irq(32+32)
(Thank you Ralf I found the answer in your example)
> Well, depends if those pins are in use.
If pins are not used I can safely share, I they are used I must share, since I
cannot partitionate per pin. This is what I understood...
> >
> > *Can I have a memory region of only 256 bytes? MMU Pages are not bigger (4k
> > 64K)?
> Yes, you actually can, Jailhouse supports subpaging. But this introduces
> a delay, because the hypervisor then traps on access and has to dispatch
> access.
I would have been a nice feature, but unfortunatly if I try to configure
/* GPIO-1 Shared */ {
.phys_start = 0x6000d000,
.virt_start = 0x6000d000,
.size = 0x100,
.flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
JAILHOUSE_MEM_IO | JAILHOUSE_MEM_ROOTSHARED,
},
/* Other GPIOs */ {
.phys_start = 0x6000d100,
.virt_start = 0x6000d100,
.size = 0xF00,
.flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
JAILHOUSE_MEM_IO,
},
instead of
/* GPIOs Shared */ {
.phys_start = 0x6000d000,
.virt_start = 0x6000d000,
.size = 0x1000,
.flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
JAILHOUSE_MEM_IO | JAILHOUSE_MEM_ROOTSHARED,
},
I get this exception:
FATAL: Invalid MMIO read, address: 6000d008, size: 2
FATAL: forbidden access (exception class 0x24)
Cell state before exception:
pc: 000000000000729c lr: 000000000000728c spsr: 20000005 EL1
sp: 0000000000009f80 esr: 24 1 1420006
x0: 0000000000009e55 x1: 000000000000000d x2: 0000000000006bf0
x3: 0000000000000100 x4: 0000000000000000 x5: 000000006000d028
x6: 0000000000000000 x7: 000000006000d068 x8: 0000000000009e52
x9: 0000000000000000 x10: 0000000000000000 x11: 0000000000007478
x12: ffffffffffffffff x13: 00000000ffffffd0 x14: 0000000000000020
x15: 0000000000000000 x16: 0000000000000000 x17: 0000000000000000
x18: 0000000000000000 x19: 000000006000d008 x20: 000000006000d018
x21: 000000006000d068 x22: 0000000000007782 x23: 0000000000007777
x24: 0000000050041440 x25: 0000000000000000 x26: 0000000050041080
x27: 000000005004141b x28: 0000000000000000 x29: 0000000000000000
> >
> >> What about the Pinmux device, i'm missing it.
> >> I just had a quick look into the X1 reference manual, and it looks like
> >> it's pretty similar to the K1, and I already successfully transferred
> >> all GPIO access to a non-root cell on the K1.
> >>
> >> Do you 'setup' and configure interrupt edges/levels of your GPIO-device
> >> from the root cell before starting the non-root cell?
> >
> > No I don't. Where can I find this approach? In any case I would like to do
> > that inside the inmate, if it is possible.
> > Just for information I'm able from the inmate cell to configure the GPIO-1,
> > I already have the registers populated with the right values and I can
> > write and read pins value. What I'm not able to do is route/enable the
> > corresponding SPI.
> Yes, but the corresponding SPI is completely different device?
>
> How did you initialise it?
>
> It's not enough to just gic_enable(gpioint), you also need to set the
> edge/level of the interrupt (rising/falling/both/...), clear the status
> register after the interrupt comes in, ...
>
> Please find my code snippet attached, but beware that this is a bloody
> fast hack and was originally written for a Jetson TK1. You may need to
> change registers. Whenever I receive an interrupt, the only thing I do
> is toggling an output.
> >
> >>> ...
> >>> },
> >>> .irqchips = {
> >>> /* GIC */ {
> >>> .address = 0x50041000,
> >>> .pin_base = 32,
> >>> .pin_bitmap = {
> >>> 0,
> >>> (1 << ((32 + 32) % 32)), /* GPIO1 */
> >> SPI 32, so I suppose you want to remap GPIO1 only, right? Then this
> >> looks good.
> >
> > Perfect.
> >
> >>> 0,
> >>> 0,
> >>> },
> >>> },
> >>> ...
> >>> };
> >>>
> >>> In the root cell configuration I made GPIO mem region
> >>> JAILHOUSE_MEM_ROOTSHARED and I turned off the GPIO-1 interrupt for the
> >>> root cell:
> >>>
> >>> .pin_bitmap = {
> >>> 0xffffffff, 0xfffffffe, 0xffffffff, 0xffffffff
> >>> },
> >> No need for that. The interrupt won't arrive in the root cell any longer
> >> once the non-root cell is started.
> >
> > Already undone, thank you.
> >
> >>>
> >>> But still I'm not hable to turn-on GPIO-1 interrupt in the inmate cell:
> >>>
> >>> if after a gic_enable_irq(32)
> >>>
> >>> I try to read the is enabler register:
> >>>
> >>> /* GIC base address for NVIDIA TEGRA X1 */
> >>> #define OSEE_GIC_BASE (0x50040000U)
> >>> #define OSEE_GICD_OFFSET (0x1000U)
> >>> #define OSEE_GICC_OFFSET (0x2000U)
> >>>
> >>> /* GICD and GICC base addresses */
> >>> #define OSEE_GICD_BASE (OSEE_GIC_BASE + OSEE_GICD_OFFSET)
> >>> #define OSEE_GICC_BASE (OSEE_GIC_BASE + OSEE_GICC_OFFSET)
> >>> #define OSEE_GICD_ISENABLER (0x0100U)
> >>>
> >>> static OsEE_bool gicd_isenabler(ISRSource source_id)
> >>> {
> >>> unsigned bit = source_id & ((1U << OSEE_GICD_ISENABLER_SHIFT) - 1U);
> >>> unsigned reg_offset = ((source_id >> OSEE_GICD_ISENABLER_SHIFT) << 2U);
> >> This looks odd... Sure that this is correct?
> >> Ralf
> >
> > I'm quite sure this is right, I took inspiration from what arm trusted
> > firmware does in its own gic-v2 driver.
> > Basically masks the lower bits of the SPI to get the "bit position inside
> > the register" + divide the SPI for 32 and multiply the result for 4 to get
> > the register offset.
> Yes.
>
> unsigned reg_offset = ((source_id >> OSEE_GICD_ISENABLER_SHIFT) << 2U);
>
> OSEE_GICD_ISENABLER_SHIFT is probably 3, right?
>
> Then you're shifting it three to the right and two back to the left :-)
>
Just for completeness since it is not really relevant for the topic:)
OSEE_GICD_ISENABLER_SHIFT is 5
> GICv2 spec:
> ISENABLER number is n = m / 32
Shifting left by five is equal to divide by 32
> Offset is 0x100 + 4*n
Then shifting right by 2 is like multipling 4
> Bit is m % 32
I got this by masking with ((1 << 5) - 1U) that is 0x1F
>
> Compare it to inmates/lib/arm-common/gic-v2.c:
> void gic_enable(unsigned int irqn)
> {
> mmio_write32(GICD_V2_BASE + GICD_ISENABLER +
> ((irqn >> 3) & ~0x3),
> 1 << (irqn & 0x1f));
> }
>
> Am i missing sth.?
> >
> >>> return (OsEE_bool) (
> >>> (osEE_mmio_read32(OSEE_GICD_BASE + OSEE_GICD_ISENABLER + reg_offset) &
> >>> (1U << bit)) != 0U);
> >>> }
> >>>
> >>> gicd_isenabler(32) return 0
> >>>
> >>> When
> >>> gicd_isenabler(27) return 1
> >>>
> >>> So do you any Idea abot what I'm doing wrong?
> >>>
> >>> In any case I would like a comment regarding inmate lib IRQ vectors for
> >>> ARM64 support (point 4 of my original mail), more I undestand how the
> >>> things works, more I suspect that the support i buggy. :)
> >>>
> >>> Regards,
> >>> Errico Guidieri
> >>>
> >
> > Thank you Ralph for your help.
> >
> > Regards,
> > Errico Guidieri
> >
Regards,
Errico Guidieri
--
You received this message because you are subscribed to the Google Groups
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.