Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 67431
b: refs/heads/master
c: 7f2c857
h: refs/heads/master
i:
  67429: c2d07b2
  67427: 3d17c6e
  67423: 1a706ee
v: v3
  • Loading branch information
Ishizaki Kou authored and Paul Mackerras committed Oct 3, 2007
1 parent 7f37934 commit a49b2cd
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b41848031ac16aee8d045e86f0b7ad3ba97e961e
refs/heads/master: 7f2c85777db26c120821bc1c9b8273a30a705a09
4 changes: 4 additions & 0 deletions trunk/arch/powerpc/platforms/celleb/beat_syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,8 @@
#define HV_rtc_write __BEAT_ADD_VENDOR_ID(0x191, 1)
#define HV_eeprom_read __BEAT_ADD_VENDOR_ID(0x192, 1)
#define HV_eeprom_write __BEAT_ADD_VENDOR_ID(0x193, 1)
#define HV_insert_htab_entry3 __BEAT_ADD_VENDOR_ID(0x104, 1)
#define HV_invalidate_htab_entry3 __BEAT_ADD_VENDOR_ID(0x105, 1)
#define HV_update_htab_permission3 __BEAT_ADD_VENDOR_ID(0x106, 1)
#define HV_clear_htab3 __BEAT_ADD_VENDOR_ID(0x107, 1)
#endif
68 changes: 68 additions & 0 deletions trunk/arch/powerpc/platforms/celleb/beat_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,37 @@ static inline s64 beat_write_htab_entry(u64 htab_id, u64 slot,
return ret;
}

static inline s64 beat_insert_htab_entry3(u64 htab_id, u64 group,
u64 hpte_v, u64 hpte_r, u64 mask_v, u64 value_v, u64 *slot)
{
u64 dummy[1];
s64 ret;

ret = beat_hcall1(HV_insert_htab_entry3, dummy, htab_id, group,
hpte_v, hpte_r, mask_v, value_v);
*slot = dummy[0];
return ret;
}

static inline s64 beat_invalidate_htab_entry3(u64 htab_id, u64 group,
u64 va, u64 pss)
{
return beat_hcall_norets(HV_invalidate_htab_entry3,
htab_id, group, va, pss);
}

static inline s64 beat_update_htab_permission3(u64 htab_id, u64 group,
u64 va, u64 pss, u64 ptel_mask, u64 ptel_value)
{
return beat_hcall_norets(HV_update_htab_permission3,
htab_id, group, va, pss, ptel_mask, ptel_value);
}

static inline s64 beat_clear_htab3(u64 htab_id)
{
return beat_hcall_norets(HV_clear_htab3, htab_id);
}

static inline void beat_shutdown_logical_partition(u64 code)
{
(void)beat_hcall_norets(HV_shutdown_logical_partition, code);
Expand Down Expand Up @@ -217,4 +248,41 @@ static inline s64 beat_put_iopte(u64 ioas_id, u64 io_addr, u64 real_addr,
ioid, flags);
}

static inline s64 beat_construct_event_receive_port(u64 *port)
{
u64 dummy[1];
s64 ret;

ret = beat_hcall1(HV_construct_event_receive_port, dummy);
*port = dummy[0];
return ret;
}

static inline s64 beat_destruct_event_receive_port(u64 port)
{
s64 ret;

ret = beat_hcall_norets(HV_destruct_event_receive_port, port);
return ret;
}

static inline s64 beat_create_repository_node(u64 path[4], u64 data[2])
{
s64 ret;

ret = beat_hcall_norets(HV_create_repository_node2,
path[0], path[1], path[2], path[3], data[0], data[1]);
return ret;
}

static inline s64 beat_get_repository_node_value(u64 lpid, u64 path[4],
u64 data[2])
{
s64 ret;

ret = beat_hcall2(HV_get_repository_node_value2, data,
lpid, path[0], path[1], path[2], path[3]);
return ret;
}

#endif
130 changes: 130 additions & 0 deletions trunk/arch/powerpc/platforms/celleb/htab.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,133 @@ void __init hpte_init_beat(void)
ppc_md.hpte_remove = beat_lpar_hpte_remove;
ppc_md.hpte_clear_all = beat_lpar_hptab_clear;
}

static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
unsigned long va, unsigned long pa,
unsigned long rflags, unsigned long vflags,
int psize)
{
unsigned long lpar_rc;
unsigned long slot;
unsigned long hpte_v, hpte_r;

/* same as iseries */
if (vflags & HPTE_V_SECONDARY)
return -1;

if (!(vflags & HPTE_V_BOLTED))
DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
"rflags=%lx, vflags=%lx, psize=%d)\n",
hpte_group, va, pa, rflags, vflags, psize);

hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags;

if (!(vflags & HPTE_V_BOLTED))
DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);

if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
hpte_r &= ~_PAGE_COHERENT;

/* insert into not-volted entry */
lpar_rc = beat_insert_htab_entry3(0, hpte_group, hpte_v, hpte_r,
HPTE_V_BOLTED, 0, &slot);
/*
* Since we try and ioremap PHBs we don't own, the pte insert
* will fail. However we must catch the failure in hash_page
* or we will loop forever, so return -2 in this case.
*/
if (unlikely(lpar_rc != 0)) {
if (!(vflags & HPTE_V_BOLTED))
DBG_LOW(" lpar err %lx\n", lpar_rc);
return -2;
}
if (!(vflags & HPTE_V_BOLTED))
DBG_LOW(" -> slot: %lx\n", slot);

/* We have to pass down the secondary bucket bit here as well */
return (slot ^ hpte_group) & 15;
}

/*
* NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
* the low 3 bits of flags happen to line up. So no transform is needed.
* We can probably optimize here and assume the high bits of newpp are
* already zero. For now I am paranoid.
*/
static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
unsigned long newpp,
unsigned long va,
int psize, int local)
{
unsigned long lpar_rc;
unsigned long want_v;
unsigned long pss;

want_v = hpte_encode_v(va, psize);
pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;

DBG_LOW(" update: "
"avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
want_v & HPTE_V_AVPN, slot, psize, newpp);

lpar_rc = beat_update_htab_permission3(0, slot, want_v, pss, 7, newpp);

if (lpar_rc == 0xfffffff7) {
DBG_LOW("not found !\n");
return -1;
}

DBG_LOW("ok\n");

BUG_ON(lpar_rc != 0);

return 0;
}

static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va,
int psize, int local)
{
unsigned long want_v;
unsigned long lpar_rc;
unsigned long pss;

DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
slot, va, psize, local);
want_v = hpte_encode_v(va, psize);
pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;

lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss);

/* E_busy can be valid output: page may be already replaced */
BUG_ON(lpar_rc != 0 && lpar_rc != 0xfffffff7);
}

static int64_t _beat_lpar_hptab_clear_v3(void)
{
return beat_clear_htab3(0);
}

static void beat_lpar_hptab_clear_v3(void)
{
_beat_lpar_hptab_clear_v3();
}

void __init hpte_init_beat_v3(void)
{
if (_beat_lpar_hptab_clear_v3() == 0) {
ppc_md.hpte_invalidate = beat_lpar_hpte_invalidate_v3;
ppc_md.hpte_updatepp = beat_lpar_hpte_updatepp_v3;
ppc_md.hpte_updateboltedpp = beat_lpar_hpte_updateboltedpp;
ppc_md.hpte_insert = beat_lpar_hpte_insert_v3;
ppc_md.hpte_remove = beat_lpar_hpte_remove;
ppc_md.hpte_clear_all = beat_lpar_hptab_clear_v3;
} else {
ppc_md.hpte_invalidate = beat_lpar_hpte_invalidate;
ppc_md.hpte_updatepp = beat_lpar_hpte_updatepp;
ppc_md.hpte_updateboltedpp = beat_lpar_hpte_updateboltedpp;
ppc_md.hpte_insert = beat_lpar_hpte_insert;
ppc_md.hpte_remove = beat_lpar_hpte_remove;
ppc_md.hpte_clear_all = beat_lpar_hptab_clear;
}
}
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/platforms/celleb/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static int __init celleb_probe(void)
return 0;

powerpc_firmware_features |= FW_FEATURE_CELLEB_POSSIBLE;
hpte_init_beat();
hpte_init_beat_v3();
return 1;
}

Expand Down
1 change: 1 addition & 0 deletions trunk/include/asm-powerpc/mmu-hash64.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ extern void hpte_init_native(void);
extern void hpte_init_lpar(void);
extern void hpte_init_iSeries(void);
extern void hpte_init_beat(void);
extern void hpte_init_beat_v3(void);

extern void stabs_alloc(void);
extern void slb_initialize(void);
Expand Down

0 comments on commit a49b2cd

Please sign in to comment.