diff options
author | Luca Barbieri <luca@luca-barbieri.com> | 2010-03-30 18:09:34 +0200 |
---|---|---|
committer | Luca Barbieri <luca@luca-barbieri.com> | 2010-03-30 18:09:34 +0200 |
commit | 6cdc400120a1ae03c7f0236b58d2eae8a1e12561 (patch) | |
tree | e1e35b4c5dbaa8aeca16749c094352029cfeaa9a | |
parent | 78a2fd9454f8188a7c58e3e0e662f5ee045c1951 (diff) |
.
-rw-r--r-- | nvlib.h | 131 | ||||
-rw-r--r-- | ramfc.cpp | 2 |
2 files changed, 88 insertions, 45 deletions
@@ -359,7 +359,7 @@ struct nv_device : public nv_region //search_shift = (reg >> 24) + 4; } - nv_ramht(std::shared_ptr<nv_ramin> ramin, int channel, uint32_t offset) + nv_ramht(std::shared_ptr<nv_ramin> ramin, uint32_t offset, int channel = -1) : nv_region(ramin->dev), ramin(ramin), channel(channel) { assert(dev->card_type >= NV_50); @@ -760,6 +760,34 @@ struct nv_device : public nv_region ptr = ramfc->ptr + dev->fifoctx_size * channel; size = dev->fifoctx_size; } + + std::shared_ptr<nv_ramht> ramht() const + { + if(dev->dev_ramht) + return dev->dev_ramht; + else + // TODO: is the high part the logarithm of the size? + return std::shared_ptr<nv_ramht>(new nv_ramht(dev->ramin, (rd32(0x80) & 0xffffff) << 4)); + } + + std::shared_ptr<nv_grctx> grctx() const + { + if(dev->card_type >= NV_40) { + unsigned offset; + if(dev->card_type >= NV_50) { + if(dev->chipset < 0x60) + offset = offset_in(*dev->ramin) + 0x200; + else + offset = rd32(0x98) << 12; + } else { + assert(dev->fifoctx_grctx >= 0); + offset = rd32(56) << 4; + } + return std::shared_ptr<nv_grctx>(new nv_grctx(dev, offset)); + } + else + return std::shared_ptr<nv_grctx>(); + } }; struct nv_hwchannel @@ -773,35 +801,31 @@ struct nv_device : public nv_region std::shared_ptr<nv_ramht> ramht; nv_hwchannel(nv_device* dev, unsigned channel, std::shared_ptr<nv_fifoctx> fifoctx = std::shared_ptr<nv_fifoctx>()) - : dev(dev), channel(channel), fifoctx(fifoctx) + : dev(dev) { - assert(channel < dev->channels); - user = dev->users->user[channel]; + update(channel, fifoctx); + } - if(!this->fifoctx) - this->fifoctx = dev->fifoctx(channel); + void update(int p_channel = -1, std::shared_ptr<nv_fifoctx> p_fifoctx = std::shared_ptr<nv_fifoctx>()) + { + if(p_channel >= 0) + channel = p_channel; - // TODO: move this out? - if(dev->card_type >= NV_20) { - unsigned offset; - if(dev->card_type >= NV_50) { - if(dev->chipset < 0x60) - offset = fifoctx->offset_in(*dev->ramin) + 0x200; - else - offset = fifoctx->rd32(0x98) << 12; - } else if(dev->card_type == NV_40) { - assert(dev->fifoctx_grctx >= 0); - offset = fifoctx->rd32(56) << 4; - } else - offset = dev->grctx_table->rd32(channel * 4) << 4; - grctx.reset(new nv_grctx(dev, offset)); - } + assert(channel < dev->channels); + + user = dev->users->user[channel]; - if(dev->card_type < NV_50) - ramht = dev->dev_ramht; + if(p_fifoctx) + fifoctx = p_fifoctx; else - // TODO: is the high part the logarithm of the size? - ramht.reset(new nv_ramht(dev->ramin, channel, (fifoctx->rd32(0x80) & 0xffffff) << 4)); + fifoctx = dev->fifoctx(channel); + + grctx = fifoctx->grctx(); + if(!grctx) + grctx = dev->grctx(channel); + ramht = fifoctx->ramht(); + if(ramht != dev->dev_ramht) + ramht->channel = channel; } bool enabled() const @@ -997,24 +1021,11 @@ struct nv_device : public nv_region else fifoctx_fifo = 0x48; - ramin.reset(new nv_ramin(this)); - users.reset(new nv_users(this)); - if(card_type < NV_50) { - ramfc.reset(new nv_ramfc(ramin)); - dev_ramht.reset(new nv_ramht(ramin)); - ramro.reset(new nv_ramro(ramin)); - ramhts = 1; - } - else - ramhts = dev->channels; - if(dev->card_type == NV_40) fifoctx_grctx = 56; else fifoctx_grctx = -1; - if(card_type == NV_20 || card_type == NV_30) - grctx_table.reset(new nv20_grctx_table(ramin)); init_grctx_info(); grctx_grclasses = -1; @@ -1025,6 +1036,29 @@ struct nv_device : public nv_region } else if(card_type == NV_30) grctx_grclasses = 0x40; + + if(card_type < NV_50) + ramhts = 1; + else + ramhts = channels; + + users.reset(new nv_users(this)); + + update(); + } + + void update() + { + ramin.reset(new nv_ramin(this)); + + if(card_type < NV_50) { + ramfc.reset(new nv_ramfc(ramin)); + dev_ramht.reset(new nv_ramht(ramin)); + ramro.reset(new nv_ramro(ramin)); + } + + if(card_type == NV_20 || card_type == NV_30) + grctx_table.reset(new nv20_grctx_table(ramin)); } static nv_device* open_default() @@ -1050,15 +1084,12 @@ struct nv_device : public nv_region std::shared_ptr<nv_ramht> ramht(unsigned channel) const { - assert(channel < ramhts); if(dev_ramht) return dev_ramht; else { - std::shared_ptr<nv_hwchannel> hwchan = hwchannel(channel); - if(!hwchan) - return std::shared_ptr<nv_ramht>(); - - return hwchan->ramht; + std::shared_ptr<nv_ramht> ramht = fifoctx(channel)->ramht(); + ramht->channel = channel; + return ramht; } } @@ -1079,6 +1110,18 @@ struct nv_device : public nv_region } } + std::shared_ptr<nv_grctx> grctx(unsigned channel) const + { + if(card_type < NV_40) { + if(card_type >= NV_20) { + unsigned offset = dev->grctx_table->rd32(channel * 4) << 4; + return std::shared_ptr<nv_grctx>(new nv_grctx(dev, offset)); + } else + return std::shared_ptr<nv_grctx>(); + } + else + return fifoctx(channel)->grctx(); + } private: void init_grctx_info() { if(card_type == NV_50) @@ -13,7 +13,7 @@ int main(int argc, char** argv) continue; if(chans) cout << '\n'; - cout << "Channel " << dec << i << " at " << hex08 << hwchan->fifoctx->offset_in(*hwchan->ramin); + cout << "Channel " << dec << i << " at " << hex08 << hwchan->fifoctx->offset_in(*dev->ramin); for(unsigned j = 0; j < dev->fifoctx_size; j += 4) { if(!(j & 15)) cout << endl; |