ME library - a new project for a more elaborate ME library

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

@crazyc :

First, if i'm not wrong, doing "_sw(1, 0xbc300008);" will enable a ME/SC irq to interrupt the processor, right ?

Second, I can see this code :

Code: Select all

   lui   $k0, 0xBC30
   lw   $k1, 0($k0)
   beq   $k1, $0, leave
   sw   $k1, 0($k0) 
the way I may interpret that code is :

1) mask = _lw(0xbc300000);

there is a pending ME/SC irq when bit 0 is set to 1, right ?

2) _sw(1, 0xbc300000);

we clear the pending ME/SC irq with bit 0 set to 1, right ?

Since for ME processor we only allow the ME/SC interrupt to occur, doing "mask = _lw(0xbc3000000); if (!mask) _sw(mask, 0xbc3000000);" is quite equivalent to doing 1) and 2), right ?
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Post by crazyc »

hlide wrote: First, if i'm not wrong, doing "_sw(1, 0xbc300008);" will enable a ME/SC irq to interrupt the processor, right ?
No, that would enable irq 0. Here's the me init code I use.

Code: Select all

void me_start() {
	u32 i;
	__asm__("mtc0 %0, $25"::"r"((unsigned int)&me_exc));
	pspSdkDisableFPUExceptions();
	_sw(0x80000000, 0xbc300008);
	__asm__("mfc0 %0, $12":"=r"(i));
	i = (i&0xffff00ff)|0x400;
	__asm__("mtc0 %0, $12"::"r"(i));
	free_lock();
	atomic_mtic_halt(1);
	while(1) {
		me_read_queue();
		atomic_check_queue_halt(1);
	}
}
See "_sw(0x80000000, 0xbc300008)" enables irq 31, the sysreg irq. To trigger the irq do "_sw(1, 0xbc100044)"
Second, I can see this code :

Code: Select all

   lui   $k0, 0xBC30
   lw   $k1, 0($k0)
   beq   $k1, $0, leave
   sw   $k1, 0($k0) 
the way I may interpret that code is :

1) mask = _lw(0xbc300000);

there is a pending ME/SC irq when bit 0 is set to 1, right ?

2) _sw(1, 0xbc300000);

we clear the pending ME/SC irq with bit 0 set to 1, right ?
No, the bit set is the number of the irq. Bit 0 is irq 0, bit 1 is irq and so on. To clear the irq, write a word with the bit of the irq set.
Since for ME processor we only allow the ME/SC interrupt to occur, doing "mask = _lw(0xbc3000000); if (!mask) _sw(mask, 0xbc3000000);" is quite equivalent to doing 1) and 2), right ?
Not quite, the store is in the delay slot, so it happens unconditionally. The only thing skipped is adding 4 to EPC, so if for some strange reason (I guess a COP0 timer interrupt could occur, may have to account for that), an irq exception occurs without any bits set in 0xbc300000, the me is halted again.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

ok, since irq 31 should be logically bit 31, it makes sense. And yes, i forgot this delay slot, silly of me. What i don't understand is why bit 0 is set to 1 with mtci (in fact this one does lead me to error). Does that mean bits are reversed for m(f/t)ic ?
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Post by crazyc »

hlide wrote:ok, since irq 31 should be logically bit 31, it makes sense. And yes, i forgot this delay slot, silly of me. What i don't understand is why bit 0 is set to 1 with mtci (in fact this one does lead me to error). Does that mean bits are reversed for m(f/t)ic ?
As far as I know, "mtic 0, $0" disables the interrupt controller entirely and opposite for "mtic 1, $0". Why it's done this way, I don't know. The normal way to disable interrupts on mips is

Code: Select all

__asm__("mfc0 %0, $12":"=r"(i));
i &= ~1;
__asm__("mtc0 %0, $12"::"r"(i)); 
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

I'm trying to find a good way not to interrupt both cpus when issuing "_sw(1, 0xbc100044)".

What follows is for ME processor to interrupt the SC processor :

Code: Select all

    .global me_interrupt_sc_processor
    .ent me_interrupt_sc_processor
me_interrupt_sc_processor:
    # suspend any future pending interrupts
    mfic    $v1, $0
    mtic    $zero, $0
    nop
    nop
    nop
    nop
    nop
    nop
    nop

    # issue an ME/SC interrupt for both cpu
    sync
    ori     $v0, 1
    lui     $at, %hi(0xbc100000)
    sw      $v0, %lo(0xbc100044)($at)
    sync
    
    # clear the pending ME/SC interrupt on ME processor
    lui     $v0, %hi(0x80000000)
    lui     $at, %hi(0xbc300000)
    sw      $v0, %lo(0xbc300000)($at)   
    sync
    
    # resume any pending interrupts
    mtic    $v1, $0
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    jr      $ra
    nop
    .end me_interrupt_sc_processor


Crazyc, did you ever try something like that ? a precision : before calling this function, you must be sure the other processor cannot interrupt your function, that's why i shall call this function only if the hardware mutex is owned by the processor calling this function so the other processor will be blocked by this mutex before interrupting .
Rangu2057
Posts: 87
Joined: Mon Jul 23, 2007 8:37 am
Location: wilmington, NC

Post by Rangu2057 »

i can code in C and a little ASM if you need some help ill be happy to join you
the questions of today are awnswered by the blood and bullets of tomorrow! ---EagleEye--- (Socom FTB2)
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Post by crazyc »

hlide wrote:I'm trying to find a good way not to interrupt both cpus when issuing "_sw(1, 0xbc100044)".
Crazyc, did you ever try something like that ? a precision : before calling this function, you must be sure the other processor cannot interrupt your function, that's why i shall call this function only if the hardware mutex is owned by the processor calling this function so the other processor will be blocked by this mutex before interrupting .
I've never tried that, I did try to set a variable to indicate which processor caused the last interrupt so the interrupt handler could know whether to ignore it. In the end, I just dodged the question and avoided doing anything important in the interrupt handler by polling the queue instead.
theHobbit
Posts: 65
Joined: Sat Sep 30, 2006 5:26 am

Post by theHobbit »

Hi there, is there any release of the library? Cuz i'm really interested in this, it think it could help improve a lot of homebrew out there.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Not yet. I've been looking over the state it's in this week... trying to determine where the most work is needed. One thing I was looking at was adding routines to change the CPU speed directly since the sce functions hang the Slim when the ME is active.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

my, i'm working on other projects and as i don't really need it and was merely proposing this public project so experienced people can improve it, i didn't work on it to a runnable state. To be frank, i thought it became a dead project since nobody else me did contribute anything.

EDIT: i mean contributing in the source of this project, of course. Note that the tips given by crazyc may be enough for most projects using ME processor.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Well, the current state is little more than my previous prx. I'm trying to decide if it should be altered to be more flexible. Once I have an idea, I'll probably at least get it working.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

I made some commits but I'm still uncertain about irq handling on ME side. CrazyC seems to imply in his examples there is no irq else the ME/SC irq. If so, it makes no sense to have a generic irq handling. And so I nearly reuse CrazyC's irq handling.

It is a long time I didn't work on it, so I'm a little lost.
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Post by crazyc »

hlide wrote:I made some commits but I'm still uncertain about irq handling on ME side. CrazyC seems to imply in his examples there is no irq else the ME/SC irq. If so, it makes no sense to have a generic irq handling. And so I nearly reuse CrazyC's irq handling.
Well, there's the timer interrupt although that's handled differently as it's internal to the CPU not attached to the irq controller. Also, the only other interrupt referenced in the ME kernel is irq 5 that does something probably avc related.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

crazyc wrote:Well, there's the timer interrupt although that's handled differently as it's internal to the CPU not attached to the irq controller. Also, the only other interrupt referenced in the ME kernel is irq 5 that does something probably avc related.
I guess we can ignore irq 5 as there is no way for us to use AVC directly. As for the Timer 0 (IP7 in Cause register), is it really important to have it as an interrupt, I wonder... anyway we can count cycles through its register Count.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

If we had a timer in the ME that could generate interrupts, preemptive multitasking would be pretty easy. We could actually have threads on the ME running all the time with the timer int driving the task switch when a thread's quantum time slice is up. I was already thinking about that and using the SC to periodically generate ints, but the timer would be even better.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

humm, so you want the ability to run irq0 timer ? if so we couldn't use "mfc0/mfc0 gpr, Count" to count elapsed cycles. Just tell me and I add the code to detect a timer0 irq.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

I'm not sure how much use you'd see of people reading the count. However, you COULD make a general purpose timer lib with it where ME threads asked for an event after so many ticks. Then have the timer subsystem keep track of which timer ints are for events and which are for the task switcher. It's pretty much how Apple handled the count down timer in the PPC under OS9. The task switcher asked for an int after X number of ticks, and processes could ask for an int after Y number, and the timer routines handled the interface to the count down timer.

That would make better use of the counter than simply allowing the current running ME task to read the count register. In fact, that would give a better timer system than you have on the SC side. :)
nikmes
Posts: 26
Joined: Tue May 20, 2008 6:00 pm

ME Access

Post by nikmes »

Can i ask if there is any sameple that demostrates they use ot ME.
Can it be used to accelerate graphics?
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

Try looking in the samples directory of PSPSDK before asking that kind of questions? :)

Code: Select all

adrahil@Rakuen:/usr/local/pspdev/psp/sdk/samples/me/basic$ ls
main.c  Makefile  me.S
You can use it for more or less anything you want to, as it is a separate processor. (Although it has been optimized for DSP and decoding, but we don't know yet how to use its AVC/VME interfaces yet)
Post Reply