The .s file I have created looks like this:

#include <sys/asm_linkage.h
ENTRY(magic_1)
sethi   (1), %g0
SET_SIZE(magic_1)

ENTRY(magic_2)
sethi   (2), %g0
SET_SIZE(magic_2)

You need

ENTRY(foo)
retl
sethi bar, %g0
SET_SIZE(foo)

Which will execute a return from leaf routine and execute the sethi in the delay slot before the branch is taken.

If you need to create a bunch of these, I would take a different tact, and generate the code on-the-fly:

#include <sys/types.h>

struct simevent {
  uint32_t s_retl;
  uint32_t s_sethi;
};

#define RETL_VAL        0x81c3e008
#define SETHI_G0_VAL    0x01000000

#define TEMPLATE { RETL_VAL, SETHI_G0_VAL }

/*
 * The low-order bits of the sethi instruction are the constant to
 * set, so you can take the nop instruction and add a constant to it
 * to get any sethi value you want into %g0.
 */

typedef void (*simevent_t)(void);

void trigger_simevent(int which_event)
{
  simevent_t s;
  struct simevent evt = TEMPLATE;
  evt.s_sethi += which_event;
  s = (simevent_t)&evt;
  s();
}

Then in your code you just do:

trigger_simevent(1);
..
trigger_simevent(2);

This will work OK because the kernel stack is executable.

- Eric
_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to