flat assembler
Message board for the users of flat assembler.

Index > OS Construction > I2C bus

Author
Thread Post new topic Reply to topic
NEOAethyr



Joined: 20 Aug 2007
Posts: 19
NEOAethyr
Hey, I need some help.
I have no clue how to use the i2c bus.

If anyone can give me some workable examples I would be grateful.
The platform I'm on is the nvidia nf2.

Base addy: 0x5000
Slave addy: 0x50 (real example of a mem slot spd)

If someone can show me an example to read that slave addy, from offsets: 0x00 -> 0xFF (0x100 in size)....
Just to get me started in the right direction.
If I can get some working code together I can figuer the rest on my own with the linux doc's out there and the bios src code.
(dissasembling the bios)

If you need more info there's linux docs out there on the nvidia nf2/3 and nf4 chipsets for it.
Or just ask me and I'll try to find what you are looking for.

Please help, this is something I really need...


What do I need it for?

Access to the cpu's doide temp via the Winbond W83L785TS-S.

To make a memmory spd read/write program for dos and my os.

To modify the spd read functions in the bios to report values for certain bytes of the spd (hardset them without modding the mem, also to give options in the bios for certain settings that are controllable only by the spd at the moment).
Also, this will allow for dead mem sticks to boot in my bios if I doit right, np, but I dn the code to start work on it.

To find the extra eeprom chip on the board used for cmos reloaded, and use it's unused space for cmos, for more setting for the bios (allmost out of space and the space I do have is used as scratch during post, it's put back but the spots I need it for..., during the srom init... well, it's not the value I set during that time and it forks over my sip options).

Plus other things, like the xbox and the vga card stuffs...


This would help me alot in the present and the future so if anyone can help me as a beginer ^^...
Thanks Smile
Post 13 May 2009, 11:00
View user's profile Send private message Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Try an electronics board
Post 13 May 2009, 13:47
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17658
Location: In your JS exploiting you and your system
revolution
I expect that the OP means the SMBus.
Post 13 May 2009, 13:55
View user's profile Send private message Visit poster's website Reply with quote
NEOAethyr



Joined: 20 Aug 2007
Posts: 19
NEOAethyr
revolution wrote:
I expect that the OP means the SMBus.


Yep Smile.




What I found confusing in the very begining is the smbios lol, you'de think it was the smbus but it's not.
You look up the entry ptr, which points to some tables which you translate.
Essentually dmi.
Gives you info on the chasis, cpu info's, ram types, etc, most of the time the info contained wihtin that structure is incorrect.
Like saying your ddr2 is edo ram, desktop instead of tower or whatever.
Totally the wrong thing though, besides the smbios shouldn't be a prob for me to finish off a parser for sooner or later.

What I'm looking for is some info's on the smbus/i2c bus.

Here is some xbox code:
Code:
define XBOX_SMB_IO_BASE                              0xC000
define XBOX_SMB_GLOBAL_ENABLE                 (XBOX_SMB_IO_BASE + 2)
define XBOX_SMB_HOST_ADDRESS                  (XBOX_SMB_IO_BASE + 4)
define XBOX_SMB_HOST_DATA                     (XBOX_SMB_IO_BASE + 6)
define XBOX_SMB_HOST_COMMAND                  (XBOX_SMB_IO_BASE + 8)

Flash_Leds:

mov dx, 0xC004             ;XBOX_SMB_HOST_ADDRESS
mov al, 0x20
out dx, al

mov dx, 0xC008              ;XBOX_SMB_HOST_COMMAND
mov al, 0x08
out dx, al

mov dx, 0xC006              ;XBOX_SMB_HOST_DATA, c = 0x80 + 0x04 + 0x20 + 0x02 = 0xA6
mov al, 0xA6
out dx, al

mov dx, 0xC000           ;XBOX_SMB_IO_BASE
in ax, dx
out dx, al

mov dx, 0xC002              ;XBOX_SMB_GLOBAL_ENABLE
mov al, 0x1A
out dx, al

mov eax, 0x01000000
Flash_Leds_Loop:
dec eax
jne Flash_Leds_Loop

mov dx, 0xC004                ;XBOX_SMB_HOST_ADDRESS
mov al, 0x20
out dx, al

mov dx, 0xC008              ;XBOX_SMB_HOST_COMMAND
mov al, 0x07
out dx, al

mov dx, 0xC006              ;XBOX_SMB_HOST_DATA
mov al, 0x01
out dx, al

mov dx, 0xC000         ;XBOX_SMB_IO_BASE
in ax, dx
out dx, al

mov dx, 0xC002              ;XBOX_SMB_GLOBAL_ENABLE
mov al, 0x1A
out dx, al

ret

Eject_Tray:

mov dx, 0xC004           ;XBOX_SMB_HOST_ADDRESS
mov al, 0x20
out dx, al

mov dx, 0xC008              ;XBOX_SMB_HOST_COMMAND
mov al, 0x0C
out dx, al

mov dx, 0xC006              ;XBOX_SMB_HOST_DATA
mov al, 0x00
out dx, al

mov dx, 0xC000         ;XBOX_SMB_IO_BASE
in ax, dx
out dx, al

mov dx, 0xC002              ;XBOX_SMB_GLOBAL_ENABLE
mov al, 0x1A
out dx, al

Eject_Tray_Delay:
mov eax, 0x01000000       ;Small delay loop
Eject_Tray_Loop:
dec eax
jne Eject_Tray_Loop

ret
    


The above is from nkpatcher and other demo's from throughout the net for the xbox.
I ported nasmx's inc files for the xbox to fasm... (still need to finish porting nkpatcher though)
It's not a perfect example, it loops ejecting the tray over and over and if you push the eject button to close the tray the code will just open it again.
But it is a working example of the smbus of some sorts.
I have tested it on my xbox... (bummer thing is that all examples for screen writing for the xbox are wrong, even the nasmx demo)

That's a nvidia chipset as well but it's not the same setup.

Here is some info I had written down:
Quote:


;NF2 Ports: (crap I gathered from windows apps)
;PCI I/O space, BA=0xCF8, size=0x8
;Port I/O Space, BA=0x4008, size=0x4
;SMBus I/O Space, BA=0x5000
;SMBus I/O Space, BA=0x5100
;Port I/O Space, BA=0xC000
;Port I/O Space, BA=0xCC00
;Port I/O Space, BA=0xD000
;Port I/O Space, BA=0xD400
;Port I/O Space, BA=0xE000
;Port I/O Space, BA=0xF000

;Memory I/O Space, BA=0xD0000000
;Memory I/O Space, BA=0xE0000000
;Memory I/O Space, BA=0xE2000000
;Memory I/O Space, BA=0xE3000000
;Memory I/O Space, BA=0xE6FFFF00
;Memory I/O Space, BA=0xE7000000
;Memory I/O Space, BA=0xE7080000
;Memory I/O Space, BA=0xE7082000
;Memory I/O Space, BA=0xE7083000
;Memory I/O Space, BA=0xE7084000

Some ports that I gathered where used from the bios so far, scanning through the src checking for "out dx, al" I think, I can't remember, I know there is a ton more though:
;0x002E
;0x002F
;0x0295
;0x0376
;0x03C0
;0x03C4
;0x03C5
;0x03CE
;0x03CF
;0x03F2
;0x03F6
;0x03F7
;0x0CF8
;0x0CF9
;0x0CFC
;0x4224
;0x4440
;0x4441
;0x4448
;0x44E5
;0x44EC
;0x44ED
;0x44EE
;0x44EF

More info's
;smbus base address: 5000
;smbus address: 50, 51, 57 (or D0, D1 and D7 as a mirror for some odd reason)

;SMBus I/O Space, BA=0x5000 <- The above slave's are on this (this is what I want access to in my code)
;SMBus I/O Space, BA=0x5100 <- I don't know what this is and it seems locked, probably vendor specific stuff's in here like the extra eeprom.

I'm pretty sure that is at least one more master but I don't remember how to find the info on it.


Info I had gathered from diff apps from my dfi nf2 lanparty ultra b board.
I could gather info from my ultra a board as well but I don't have it up and running at the moment, no drive in it.

I know there is at least 2 more slave addresses on the main smbus.
52 or 53, I can't remmember which, for slot 3, also for the non-existant slot 4.

Here is some src code from nvidia that sliped out from asus:

Code:
SMBUS_PORT2                     EQU     0A000h;SMBus2_Port      ;defined in K8 bios.cfg.

HW_MONITOR_SMBUS_READ_ADDR      EQU     5Bh ;SMBUS address for read hardware monitor data
HW_MONITOR_SMBUS_WRITE_ADDR     EQU     5Ah ;SMBUS address for read hardware monitor data

SMSC_LPC47M15_SMB_REG_CONFIGURATION     EQU     40h     ;HW monitor config register.
CPU_TEMP_SMBUS_OFFSET           EQU     26h ;SMBUS offset coresponding to CPU Temp            ;N02
BOARD_TEMP_SMBUS_OFFSET         EQU     27h ;SMBUS offset coresponding to Motherboard Temp    ;N02

;SMI related define
SMI_IO_BASE_ADDR                EQU     SYSTEM_PORT
SW_SMI_STATUS_REG               EQU     2Fh
SW_SMI_SCRATCH0_REG             EQU     80h         ;N03
SW_SMI_SCRATCH1_REG             EQU     84h
SW_SMI_SCRATCH2_REG             EQU     88h         ;N03
SW_SMI_SCRATCH3_REG             EQU     8Ch         ;N03
SW_SMI_SCRATCH4_REG             EQU     90h         ;N03
SW_SMI_SCRATCH5_REG             EQU     94h         ;N03
SW_SMI_SCRATCH6_REG             EQU     98h         ;N03
SW_SMI_SCRATCH7_REG             EQU     9Ch         ;N03

;N10 start        
;Used for GetMemAddrInfo
DIMM0_SMBUSADDR                 EQU     51h     ;Smbus address  ;N11
DIMM0_SLOT_NO                   EQU     0       ;Corresponding slot no.
DIMM0_SMBUS_SEG                 EQU     0       ; smbus segment                   
DIMM1_SMBUSADDR                 EQU     52h                     ;N11
DIMM1_SLOT_NO                   EQU     1
DIMM1_SMBUS_SEG                 EQU     0                          
DIMM2_SMBUSADDR                 EQU     50h     ;N11     
DIMM2_SLOT_NO                   EQU     2
DIMM2_SMBUS_SEG                 EQU     0                          
DIMM3_SMBUSADDR                 EQU     0     
DIMM3_SLOT_NO                   EQU     3
DIMM3_SMBUS_SEG                 EQU     0                          
;N10 end
    


A note on the above define for "SMI_IO_BASE_ADDR -> SYSTEM_PORT", it's missing out of the src code.
There's 2 more files in the src (2 I have, 2 missing).

If you want to see that leaked code look on google for: "NvidiaSU_v09" or somethign like that and you'll find it.
Comes with some nf2 and nf3 info's.

Here is some examples out of the asm for that leaked code (not fasm baised):

Code:
;[]======================================================================[]
; CS_I2CReadByte: this is the exact copy from chipboot.asm I2CByteRead
;               code in chipboot.asm will not exist anymore after system
;               boot to OS. This is used only for SMM mode.
;
;Input    : BL - 8 bits I2C ID address,AL - byte index
;Output   : BH - value return if carry cleared
;           Fail - if carr set
;[]======================================================================[]
CS_I2CReadByte  Proc    Near
        push    dx
        
        ; Disable stuff in extended control reg.
        push    ax
        mov     al, 00
        mov     dx, SMBUS_PORT2 + 3Eh
        out     dx, al
        
        ;Send a not in use to protocol reg.
        mov     dx, SMBUS_PORT2 + 00h
        out     dx, al
        
        pop     ax
        
        mov     ah, al                  ; byte index
        mov     al, bl
        mov     dx, SMBUS_PORT2 + 02h
        out     dx, ax                  ; address and index
        ; wait SMbus ready
        ;ROM_CALL Chk_SMBus_READY ;N18
        ; start I2C read operation
        newiodelay
        mov     dx, SMBUS_PORT2 + 00h
        mov     al, 07h                 ; MCP_SMB_PRTCL_PROTOCOL_READ_BYTE
        out     dx, al
        newiodelay
        ; check status OK ?
        call    CS_Chk_SMBus_READY
        jc      CS_I2C_ReadFail          ; SMBus Fail
        newiodelay
        ; read data
        mov     dx, SMBUS_PORT2 + 04h    ; MCP_CONST_SMB1_BASE + MCP_SMB_DATA_00
        in      al, dx
        mov     bh, al                  ; value return
CS_I2C_ReadFail:

        pop     dx
        ret
CS_I2CReadByte  Endp
;-------------------------------------------------
; CS_I2CWriteByte: this is the exact copy from chipboot.asm I2CByteWrite
;               code in chipboot.asm will not exist anymore after system
;               boot to OS. This is used only for SMM mode.
;
;Input    : BL - 8 bits I2C ID address,AL - byte index
;         : BH - value to write
;Output   : Fail - if carr set
;-------------------------------------------------
CS_I2CWriteByte    Proc    Near
        push    dx

        mov     ah, al                  ; byte index
        mov     al, bl
        mov     dx, SMBUS_PORT2 + 02h
        out     dx, ax                  ; address and index
        newiodelay
        ; put data to SMbus Base + 6
        mov     al, bh
        mov     dx, SMBUS_PORT2 +04h
        out     dx, al                  ; Data0
        newiodelay
        ; wait SMbus ready
        call    CS_Chk_SMBus_READY
        ; start I2C write operation
        newiodelay
        mov     dx, SMBUS_PORT2 + 00h
        mov     al, 06h                 ; MCP_SMB_PRTCL_PROTOCOL_WRITE_BYTE
        out     dx, al
        ; check status OK ?
        call    CS_Chk_SMBus_READY
        
        pop     dx
        ret
CS_I2CWriteByte    Endp
;[]======================================================================[]
; CS_Chk_SMBus_READY: this is the exact copy from chipboot.asm Chk_SMBus_READY
;               code in chipboot.asm will not exist anymore after system
;               boot to OS. This is used only for SMM mode.
;
;Input  : None
;Output : Carry set means error; carry clear means ready.
;[]======================================================================[]
        
CS_Chk_SMBus_READY      Proc    Near
        push    dx
        push    cx
        push    ax
        mov     dx, SMBUS_PORT2 + 01h     ;Status port
        clc
        
        mov     cx, 2000h
CS_Chk_I2C_OK:
        newiodelay
        in      al, dx                   ;get status
        or      al, al                   ;N18
        jz      CS_Chk_I2C_OK            ;not ready

        test    al, 80h                  ;is finished
        jnz     CS_Clear_final

        test    al, 01Fh
        jz      CS_Clear_final

        and     al, 01Fh
        cmp     al, 01Ah                ; SMBus busy?
        jne     CS_SMBus_Err

        ;out     dx, al                   ;clear status
        loop    CS_Chk_I2C_OK

CS_SMBus_Err:
        
        stc
CS_Clear_final:
        out     dx, al                   ;clear status
        pop     ax
        pop     cx
        pop     dx
        ret
CS_Chk_SMBus_READY      Endp
    


The prob is, all that src really contains is chipset and board specific info's on the chipset and temps.
There's no spd read function in it for some reason.

It mostly talks about the smi interface, what reg's ont he chipset need to be set and etc for the chipset system management irq.
Which to be onest, I'm totally not ready for when I can't get my own unreal mode code to stop faulting the cpu on jmp lol Smile (after bootsector, in bootsector it's fine...).

The 2 leaked src packages for the award bios'es don't help me either.
They are old as heck, and so they are pretty much useless when it comes to this.

There's more info as I said before in the form of linux drivers on google.
For the nf2/3/4.
Using a mix of c and asm, and extern like thingys and wierd stuffs that don't help me understand.
(Though it probably has the best info on the actual ports used and cmds)

As much as I hate to ask this, I gotta ask for a small example that would actually read a byte or 2 from my spd into a reg or mem varible or something that I can work from.

So far this is like taking on usb, I just don't have a clue.
This looks easy enough, seems like I just need the port info and how to access it.


I'm guessing I need to send a cmd to a certain port.
Like I need to say I want to read this slave addy, and I want to read this offset from that slave.
Like the cmos kinda.

I just don't know how though.

I hope I didn't post to much spam or something.
The more the better maybe... ^^


Anyways to be clear:
Smbus master 0x5000
Slave: 0x50
That is what I want to access.
If I can read a byte from that correctly, I should beable to work out the rest.
Post 13 May 2009, 15:46
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17658
Location: In your JS exploiting you and your system
revolution
I think you need to find info about the SMBus controller chip. The general I2C bus is adequately documented by Philips.

Where is the SMBus controller chip? Is it inside the north/south bridge or a separate chip?

I know that speedfan reads the SMBus, so code for it can't be too hard to find. There might be some open source semi-generic code that you can find.
Post 13 May 2009, 15:56
View user's profile Send private message Visit poster's website Reply with quote
NEOAethyr



Joined: 20 Aug 2007
Posts: 19
NEOAethyr
It's in the south bridge I believe.

http://www.mjmwired.net/kernel/Documentation/i2c/busses/i2c-nforce2
https://www.linuxhq.com/kernel/v2.6/20-rc3/drivers/i2c/busses/i2c-nforce2.c
Thre must be a full version of the above 2 somewhere..., I don't have anything new related to linux though on my end, dialup.

http://smbus.org/specs/smb10.pdf
http://smbus.org/specs/smbus110.pdf
http://smbus.org/specs/smbus20.pdf
http://smbus.org/specs/smbus_cmi10.pdf
http://smbus.org/specs/smbus_driver_ext_arch10.pdf

http://smbus.org/specs/smbb10.pdf
Note that the installation check function in this pdf fails on my system.
So I'm assuming that the bios interface functions for this plain don't work on my end.


Oh, I had a copy of the nf2 i2c driver for linux on my drive as a html file..., the ftp link for it is down so I'm posting.

Quote:

/*
SMBus driver for nVidia nForce2 MCP

Added nForce3 Pro 150 Thomas Leibold <thomas@plx.com>,
Ported to 2.5 Patrick Dreker <patrick@dreker.de>,
Copyright (c) 2003 Hans-Frieder Vogt <hfvogt@arcor.de>,
Based on
SMBus 2.0 driver for AMD-8111 IO-Hub
Copyright (c) 2002 Vojtech Pavlik

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
SUPPORTED DEVICES PCI ID
nForce2 MCP 0064
nForce2 Ultra 400 MCP 0084
nForce3 Pro150 MCP 00D4
nForce3 250Gb MCP 00E4
nForce4 MCP 0052
nForce4 MCP-04 0034
nForce4 MCP51 0264
nForce4 MCP55 0368

This driver supports the 2 SMBuses that are included in the MCP of the
nForce2/3/4/5xx chipsets.
*/

/* Note: we assume there can only be one nForce2, with two SMBus interfaces */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <asm/io.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>");
MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");


struct nforce2_smbus {
struct i2c_adapter adapter;
int base;
int size;
};


/*
* nVidia nForce2 SMBus control register definitions
* (Newer incarnations use standard BARs 4 and 5 instead)
*/
#define NFORCE_PCI_SMB1 0x50
#define NFORCE_PCI_SMB2 0x54


/*
* ACPI 2.0 chapter 13 SMBus 2.0 EC register model
*/
#define NVIDIA_SMB_PRTCL (smbus->base + 0x00) /* protocol, PEC */
#define NVIDIA_SMB_STS (smbus->base + 0x01) /* status */
#define NVIDIA_SMB_ADDR (smbus->base + 0x02) /* address */
#define NVIDIA_SMB_CMD (smbus->base + 0x03) /* command */
#define NVIDIA_SMB_DATA (smbus->base + 0x04) /* 32 data registers */

#define NVIDIA_SMB_STS_DONE 0x80
#define NVIDIA_SMB_STS_ALRM 0x40
#define NVIDIA_SMB_STS_RES 0x20
#define NVIDIA_SMB_STS_STATUS 0x1f

#define NVIDIA_SMB_PRTCL_WRITE 0x00
#define NVIDIA_SMB_PRTCL_READ 0x01
#define NVIDIA_SMB_PRTCL_QUICK 0x02
#define NVIDIA_SMB_PRTCL_BYTE 0x04
#define NVIDIA_SMB_PRTCL_BYTE_DATA 0x06
#define NVIDIA_SMB_PRTCL_WORD_DATA 0x08
#define NVIDIA_SMB_PRTCL_PEC 0x80

static struct pci_driver nforce2_driver;

/* Return -1 on error */
static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data * data)
{
struct nforce2_smbus *smbus = adap->algo_data;
unsigned char protocol, pec, temp;

protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
NVIDIA_SMB_PRTCL_WRITE;
pec = (flags & I2C_CLIENT_PEC) ? NVIDIA_SMB_PRTCL_PEC : 0;

switch (size) {

case I2C_SMBUS_QUICK:
protocol |= NVIDIA_SMB_PRTCL_QUICK;
read_write = I2C_SMBUS_WRITE;
break;

case I2C_SMBUS_BYTE:
if (read_write == I2C_SMBUS_WRITE)
outb_p(command, NVIDIA_SMB_CMD);
protocol |= NVIDIA_SMB_PRTCL_BYTE;
break;

case I2C_SMBUS_BYTE_DATA:
outb_p(command, NVIDIA_SMB_CMD);
if (read_write == I2C_SMBUS_WRITE)
outb_p(data->byte, NVIDIA_SMB_DATA);
protocol |= NVIDIA_SMB_PRTCL_BYTE_DATA;
break;

case I2C_SMBUS_WORD_DATA:
outb_p(command, NVIDIA_SMB_CMD);
if (read_write == I2C_SMBUS_WRITE) {
outb_p(data->word, NVIDIA_SMB_DATA);
outb_p(data->word >> 8, NVIDIA_SMB_DATA+1);
}
protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
break;

default:
dev_err(&adap->dev, "Unsupported transaction %d\n", size);
return -1;
}

outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR);
outb_p(protocol, NVIDIA_SMB_PRTCL);

temp = inb_p(NVIDIA_SMB_STS);

if (~temp & NVIDIA_SMB_STS_DONE) {
udelay(500);
temp = inb_p(NVIDIA_SMB_STS);
}
if (~temp & NVIDIA_SMB_STS_DONE) {
msleep(10);
temp = inb_p(NVIDIA_SMB_STS);
}

if ((~temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) {
dev_dbg(&adap->dev, "SMBus Timeout! (0x%02x)\n", temp);
return -1;
}

if (read_write == I2C_SMBUS_WRITE)
return 0;

switch (size) {

case I2C_SMBUS_BYTE:
case I2C_SMBUS_BYTE_DATA:
data->byte = inb_p(NVIDIA_SMB_DATA);
break;

case I2C_SMBUS_WORD_DATA:
data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << Cool;
break;
}

return 0;
}


static u32 nforce2_func(struct i2c_adapter *adapter)
{
/* other functionality might be possible, but is not tested */
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
}

static struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = nforce2_access,
.functionality = nforce2_func,
};


static struct pci_device_id nforce2_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
{ 0 }
};

MODULE_DEVICE_TABLE (pci, nforce2_ids);


static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
int alt_reg, struct nforce2_smbus *smbus, const char *name)
{
int error;

smbus->base = pci_resource_start(dev, bar);
if (smbus->base) {
smbus->size = pci_resource_len(dev, bar);
} else {
/* Older incarnations of the device used non-standard BARs */
u16 iobase;

if (pci_read_config_word(dev, alt_reg, &iobase)
!= PCIBIOS_SUCCESSFUL) {
dev_err(&dev->dev, "Error reading PCI config for %s\n",
name);
return -1;
}

smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
smbus->size = 64;
}

if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
smbus->base, smbus->base+smbus->size-1, name);
return -1;
}
smbus->adapter.owner = THIS_MODULE;
smbus->adapter.id = I2C_HW_SMBUS_NFORCE2;
smbus->adapter.class = I2C_CLASS_HWMON;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;
smbus->adapter.dev.parent = &dev->dev;
snprintf(smbus->adapter.name, I2C_NAME_SIZE,
"SMBus nForce2 adapter at %04x", smbus->base);

error = i2c_add_adapter(&smbus->adapter);
if (error) {
dev_err(&smbus->adapter.dev, "Failed to register adapter.\n");
release_region(smbus->base, smbus->size);
return -1;
}
dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n", smbus->base);
return 0;
}


static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct nforce2_smbus *smbuses;
int res1, res2;

/* we support 2 SMBus adapters */
if (!(smbuses = kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL)))
return -ENOMEM;
pci_set_drvdata(dev, smbuses);

/* SMBus adapter 1 */
res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1");
if (res1 < 0) {
dev_err(&dev->dev, "Error probing SMB1.\n");
smbuses[0].base = 0; /* to have a check value */
}
/* SMBus adapter 2 */
res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2");
if (res2 < 0) {
dev_err(&dev->dev, "Error probing SMB2.\n");
smbuses[1].base = 0; /* to have a check value */
}
if ((res1 < 0) && (res2 < 0)) {
/* we did not find even one of the SMBuses, so we give up */
kfree(smbuses);
return -ENODEV;
}

return 0;
}


static void __devexit nforce2_remove(struct pci_dev *dev)
{
struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev);

if (smbuses[0].base) {
i2c_del_adapter(&smbuses[0].adapter);
release_region(smbuses[0].base, smbuses[0].size);
}
if (smbuses[1].base) {
i2c_del_adapter(&smbuses[1].adapter);
release_region(smbuses[1].base, smbuses[1].size);
}
kfree(smbuses);
}

static struct pci_driver nforce2_driver = {
.name = "nForce2_smbus",
.id_table = nforce2_ids,
.probe = nforce2_probe,
.remove = __devexit_p(nforce2_remove),
};

static int __init nforce2_init(void)
{
return pci_register_driver(&nforce2_driver);
}

static void __exit nforce2_exit(void)
{
pci_unregister_driver(&nforce2_driver);
}

module_init(nforce2_init);
module_exit(nforce2_exit);



That's all I have except for info related to the nf4's 2nd master chan, slave addy 0x2e causing resets on scan for linux.
Not really important though.

There is one thing I wanted to say that I should of before.
If I mess up on this when reading the spd, it's not a biggy.
I don't care if I kill some sticks of ram, I have my ways of flashing dead ram sticks so it's all good.
I'm fully aware of the danger.


Phillips huh, I'll look it up.
Some new info has come to light though, apperently some amd chipset has a simuler interface to the nvidia one.
Perhaps I can find some nasm/masm code for that.

Main prob has been that I've been finding junk on hobbist stuffs, self made boards and the like for busses that I don't have (totally diff addys and cmds).
Or linux drivers that I can't understand.

Stuff like pysical bus cycles and stuff, when I don't care lol, I just wanna see some asm in these datasheets Smile.
It's like the darn 8254 pic, but with even less to go on.
I managed that one given 2 diff datasheets.
But this is making me struggle a bit lol.

I just don't know where to start, but I'll try porting the leaked asm nvidia code.
I'll also look around for the phillips info's.
Post 13 May 2009, 16:33
View user's profile Send private message Reply with quote
NEOAethyr



Joined: 20 Aug 2007
Posts: 19
NEOAethyr
I found these on my drive this morning, I knew I had them somewhere...

www.nxp.com/acrobat_download/literature/9398/39340011.pdf
i2c.bus.specification.pdf <-- not sure where I can find..., but I have it

I just found this looking for the above link, alot of stuff to sort through I'll have to check it out ^^ :O.
http://www.educypedia.be/electronics/I2C.htm

I ported the nvidia code over to fasm.

macros:
Code:
macro NEWIODELAY
{
;  if Cleanup = 1          ;I don't have this defined in my os, only ROMBuild
;                nop
;                nop
;        else
                out 0xEB, al    ;NEWIODELAY
;        end if
}
    


SMBUS.asm (so far...)
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SMBUS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Defines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;0x5000, 0x5100
;0x50, 0x51

SMBUS_PORT2     dw 0xA000       ;SMBus2_Port, defined in K8 bios.cfg.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Funcions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;This is the exact copy from chipboot.asm
;I2CByteRead code in chipboot.asm will not exist anymore after system boot to OS.
;This is used only for SMM mode.
;Input:               BL - 8 bits I2C ID address, AL - byte index
;Output:     BH - value return if carry cleared
;         Fail - if carr set
CS_I2CReadByte:
push dx
push ax                         ;Disable stuff in extended control reg.
mov al, 0x00
mov dx, SMBUS_PORT2 + 0x3E
out dx, al
mov dx, SMBUS_PORT2 + 0x00       ;Send a not in use to protocol reg.
out dx, al
pop ax
mov ah, al                       ;byte index
mov al, bl
mov dx, SMBUS_PORT2 + 0x02
out dx, ax                   ;address and index
                          ;wait SMbus ready, ROM_CALL Chk_SMBus_READY, N18, start I2C read operation
NEWIODELAY
mov dx, SMBUS_PORT2 + 0x00
mov al, 0x07                  ;MCP_SMB_PRTCL_PROTOCOL_READ_BYTE
out dx, al
NEWIODELAY
                               ;check status OK ?
call CS_Chk_SMBus_READY
jc CS_I2C_ReadFail             ;SMBus Fail
NEWIODELAY
;read data
mov dx, SMBUS_PORT2 + 0x04   ;MCP_CONST_SMB1_BASE + MCP_SMB_DATA_00
in al, dx
mov bh, al                       ;value return
CS_I2C_ReadFail:
pop dx
ret

;This is the exact copy from chipboot.asm
;I2CByteWrite code in chipboot.asm will not exist anymore after system boot to OS.
;This is used only for SMM mode.
;Input:                BL - 8 bits I2C ID address, AL - byte index
;                BH - value to write
;Output:     Fail - if carr set
CS_I2CWriteByte:
push dx
mov ah, al     ;byte index
mov al, bl
mov dx, SMBUS_PORT2 + 0x02
out dx, ax   ;address and index
NEWIODELAY
mov al, bh  ;put data to SMbus Base + 0x06
mov dx, SMBUS_PORT2 + 0x04
out dx, al      ;Data0
NEWIODELAY
call CS_Chk_SMBus_READY ;wait SMbus ready
NEWIODELAY ;start I2C write operation
mov dx, SMBUS_PORT2 + 0x00
mov al, 0x06        ;MCP_SMB_PRTCL_PROTOCOL_WRITE_BYTE
out dx, al
call CS_Chk_SMBus_READY     ;check status OK ?
pop dx
ret

;This is the exact copy from chipboot.asm
;Chk_SMBus_READY code in chipboot.asm will not exist anymore after system boot to OS.
;This is used only for SMM mode.
;Input:                None
;Output:    Carry set means error, carry clear means ready.
CS_Chk_SMBus_READY:
push dx
push cx
push ax
mov dx, SMBUS_PORT2 + 0x01       ;Status port
clc
mov cx, 0x2000
CS_Chk_I2C_OK:
NEWIODELAY
in al, dx                  ;get status
or al, al                        ;N18
jz CS_Chk_I2C_OK                ;not ready
test al, 0x80                     ;is finished
jnz CS_Clear_final
test al, 0x1F
jz CS_Clear_final
and al, 0x1F
cmp al, 0x1A                        ;SMBus busy?
jne CS_SMBus_Err
;out dx, al                 ;clear status
loop CS_Chk_I2C_OK
CS_SMBus_Err:
stc
CS_Clear_final:
out dx, al                    ;clear status
pop ax
pop cx
pop dx
ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    


Yes I know it needs optimizing and cleaning up.
It needs to work 1st though lol.


Cmd CLI function called TEST:
Code:
Cmd_Test:
push bx
mov al, 0x00                       ;AL - byte index
mov bl, 0x50                        ;BL - 8 bits I2C ID address
call CS_I2CReadByte
jc SMB_Test_Fail
mov al, bh
pop bx
mov di, 0x0001
call Print_Hex
call Print_Msg_Ret
jmp Cmd_Ret

SMB_Test_Fail:
pop bx
lea dx, [Msg_Error+bx]
call Print_String
jmp Cmd_Ret
    


I push bx because my os uses bx as a dynamic addy thingy for rom loading, as it goes in rom when I'm done to certain points (have an previous ver it in shadow ram right now).
I mean, org is not 0x100 in rom, nor is it barely ever 0x0000, it's dynamic so the code needs to be like that.
I push and pop cs to get the valu of bx, using some call trickery...
Not that important though, it might look odd so I thaught I'de explain it.


I've tried diff offsets instead of 0x00.
I've tried a diff addy instead of 0xA000.

What i'm getting...
The functions aren't failing, none of them are.
The values reported back are 0xFF, allways...

I've notcied the leaked nvidia code I ported is award bios code for sure, 100%.
I'lll have to check that and see if I can find the orignal in chipboot.
I don't have a k8 file I know that, I do have some k7 stuffs though.
I might beable to find the missing equates in the nvidia src from the award src.

If I can find the code in the award src, I should beable to find that actual code used in my bios'es dissasembled code.
If so then I might beable to figuer out something.
At how it works or something.

I dn though dudes, this is over my head, something I just don't know how to use Sad.
I can't find a single decent example out there on the net for this stuff.
Nor is the leaked codes helping :\.

Though it does look somewhat simuler to the xbox code...
C, S, etc etc, whatever though cmd things mean.
I might beable to figuer this out.


If anyone has done this before please step up.
Any kind of example in asm could help alot...
Post 14 May 2009, 11:57
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17658
Location: In your JS exploiting you and your system
revolution
NEOAethyr wrote:
Yes I know it needs optimizing and cleaning up.
It needs to work 1st though lol.
Actually this is not really a laughing matter. Far too many people get caught in the optimisation-or-die mode too early. I am glad to see that you are approaching this in the proper fashion.

Also, I don't actually see any reason to optimise this code. It is not as though it will run 24/7 millions of times per minute. So no need to bother optimising, just get it working and leave it. Then you are free to move on to something else more productive.
Post 14 May 2009, 12:08
View user's profile Send private message Visit poster's website Reply with quote
NEOAethyr



Joined: 20 Aug 2007
Posts: 19
NEOAethyr
I totally agree.
I've made that mistake a few times myself.

I've learned that:
1. Code must 1st work 100%.
2. Optimize for size.
3. Optimize for mem bandwith.

The 3rd step, the cpu is allways going to be faster then mem.
You could bloat your code to heck, but as long as you never touch the mem, your code is still going to be fast enough.
There's gotta be a balance and etc, depending on what varibles you need to keep in mem and such.

That I think is the main speed prob with c code.
Even or especially if you use inline code, it's going to use the stack or mem like a mofo.

How I optimize is I look for code I think I can reduce in output size, and or code lines (the fewer lines it is the easier it is to work with).
I comment out the line or 2 I want to optimize, put together the new code.
Check to see if it works, and check the output size of the binary.
If it's all good, it's been optimized.
Then I continue with the next line or so that I see may need optimizing.

After each new optimized code line has been done, I del the old commented out code.
And there you go.

Certain reg's I try to keep the same throught the program.
In cases of certain soft irq's, or if I pass controll over to another program (load), I push those reg's to the stack before I push the ret seg:offset.
When I ret back, I pop my reg's and it's all good.

I only do that with one reg though, bx.
I can use bx as an offset reg, so I use that for my org directive throught my program.
It may double my code size using it the way I do, "lea dx, [mem_offset+bx]" and etc.
But it's much better then calling my org finding function over and over throught my program.

My code was 5 times bigger before I learned howto use the lea instruction to my advantage.

And I only use that setup because of my program needs to beable to load into diff offsets at diff times.

It's all good when it's working right.
But it's not good when you paste in someone's so called super optimized code that never worked in the 1st place.

I've posted such code before here in the forum in the form of a lba translation...
Since then I've fixed it, then figuered out that chs kinda sucks when it comes to actual hd access....


Anyways, I took a shower and took a look at the old award bios src code I have.
Looking at chipboot.asm specifically.

I found this:

Code:
Check_CAS_Latency Proc    Near
                mov     al,SDRAM_LT_AUTO_CMOS NMI_OFF
               ROM_CALL Get_Cmos
           and     al,SDRAM_LT_AUTO_CMOS_BITS
          cmp     al,SDRAM_LT_AUTO_CMOS_BITS
          je      short CAS_Lt_Auto

               mov     bx,32                           ;assign a dummy value
               xor     ah,ah                           ;clear AH
           mov     dx,SDRAM_LT_AUTO_CMOS_BITS
          bsf     cx,dx
               bsf     bx,ax
               xchg    ax,bx
               xor     bl,bl
               cmp     cx,ax
               jne     short @F

                mov     bl,SDRAM_LT_CMOS_BITS
       @@:

         mov     al,SDRAM_LT_CMOS NMI_OFF
            ROM_CALL Get_Cmos
           and     al,NOT SDRAM_LT_CMOS_BITS
           or      al,bl
               mov     ah,SDRAM_LT_CMOS NMI_OFF
            xchg    ah,al
               ROM_CALL Set_Cmos

               jmp     CAS_Latency_Auto_End

CAS_Lt_Auto:

            mov     cx,(TSC_ID SHL 11)+0fch
             Rom_call Get_Ct
             test    al,10h                  ;Is 100Mhz ?
                mov     si,0f090h               ;66Mhz
              jz      short @F
            mov     si,0a060h               ;100 Mhz
    @@:

         mov     bl,SDRAM_LT_CMOS_BITS   ;set CAS=3 flag
             ror     ebx,16                  

;Check byte18 SDRAM CAS Latency
             mov     bl,0a0h 
    Check_CAS_Start:
                mov     al,18
               mov     di,offset DGROUP:@F
             jmp     I2CByteRead
 @@:
             jc      short @F
            test    bh,00000010b
                jz      short CAS_33
        @@:
             add     bl,2
                cmp     bl,0a6h
             jbe     short Check_CAS_Start

;Check byte09 SDRAM cycle time
         mov     bl,0a0h 
    Check_cycl_Start:
               mov     al,23                   
            mov     di,offset DGROUP:@F
             jmp     I2CByteRead
 @@:
             jc      short @F
            cmp     bh,0                    
            jne     short Cyc_Sure          
            mov     bh,0ffh                 
    Cyc_Sure:                           
            mov     ax,si
               cmp     bh,ah
               ja      short CAS_33
        @@:
             add     bl,2
                cmp     bl,0a2h
             jbe     short Check_cycl_Start


;Check byte10 SDRAM access time
           mov     bl,0a0h 
    Check_acct_Start:
               mov     al,24                   
            mov     di,offset DGROUP:@F
             jmp     I2CByteRead
 @@:
             jc      short @F
            cmp     bh,0                    
            jne     short Acc_Sure          
            mov     bh,0ffh                 
    Acc_Sure:                           
            mov     ax,si
               cmp     bh,al
               ja      short CAS_33
        @@:
             add     bl,2
                cmp     bl,0a2h
             jbe     short Check_acct_Start

          xor     ebx,ebx                 ;set CAS=2 flag
CAS_33:
              ror     ebx,16                  ;get CAS flag

           mov     al,SDRAM_LT_CMOS NMI_OFF
            ROM_CALL Get_Cmos
           and     al,NOT SDRAM_LT_CMOS_BITS
           or      al,bl
               mov     ah,SDRAM_LT_CMOS NMI_OFF
            xchg    ah,al
               ROM_CALL Set_Cmos

CAS_Latency_Auto_End:
          jmp     Check_CAS_Latency_Exit
Check_CAS_Latency     Endp
    


Now I have some code to scan for that uses the smbus read function.
However I could not find this code, this is to old for my bios.
I might find it later though when I gather more info.


Code:
;Function : Read a I2C byte value
;Input    : BL - I2C ID address,AL - byte index
;Output   : BH - value return if carry cleared
;       Fail - if carr set
I2CByteRead:

      ;set index byte to read
             mov     dx,SMBus_Port +03h
          out     dx,al                   ;Index
              NEWIODELAY

      ;set I2C ID No.
             mov     dl,04h
              mov     al,bl                   ;E2PROM read cmd
            or      al,01H                  ;bit 0=1 for I2C read
               out     dx,al
               NEWIODELAY

      ;wait SMbus ready
           ROM_CALL        Chk_SMBus_READY

 ;start I2C read operation
           mov     dl,02h
              mov     al,48h
              out     dx,al                   ;read data
          NEWIODELAY

      ;wait for a while
           mov     cx,100h
     @@:                         
            newiodelay
          loop    short @B

        ;check status OK ?
          ROM_CALL  Chk_SMBus_READY
           jc      short I2CFaile          ;SMBus Fail

     ;read data
          mov     dl,05                   ;data port
          in      al,dx                   ;Data0
              NEWIODELAY
          mov     bh,al                   ;value return
I2CFaile:
              jmp     di

Chk_SMBus_READY       Proc    near
                
            mov     dx,SMBus_Port + 0;status port
               clc
         mov     cx,0800h
Chk_I2c_OK:
         in      al,dx           ;get status
         NEWIODELAY
          out     dx,al           ;clear status
               NEWIODELAY

              test    al, 02H         ;termination of command ?
           jnz     short Clear_final

               and     al, NOT 40H     ;mask INUSE bit ;R06
                or      al,al           ;status OK ?
                jz      short Clear_final

               test    al,04h          ;device error
               jnz     short SMBus_Err

         loop    short Chk_I2c_OK
    ;SMbus error due to timeout
SMBus_Err:

           stc
         ret
Clear_final:
             clc
         ret
Chk_SMBus_READY  endp
    


That is the code that is in chipboot.asm, the i2c read function.
It seems it was called by a diif name back then.
And it's alot diff.
I could not find it in my bios using the old code to go by.

So I checked for the functions around it, if I could find those, I could look around them and possibly find the new i2c read function.
Nogo, until I looked for this:

Code:
Ct_Enable_C_Shadow        proc    near
                push    cx
          mov     cx,(TSC_ID SHL 8) + 051H        ;enable shadow R/W
          call    Get_Ct
              or      al,00000011b
                call    Set_Ct
              pop     cx
          ret
Ct_Enable_C_Shadow       endp
    


I scanned for push cx.
Not something I would normally start with, to commen.
However, it's not so commen as you would think.
Some modules plain did not have any instances of it.

I didn't finish up my scan, because I managed to find code of interest pretty quickly.


Here is what I found in my main bios module, 1st segment:

Code:
0000C3B7  51                push cx           ;potential smbus
0000C3B8  51                push cx
0000C3B9  BA0251            mov dx,0x5102
0000C3BC  8AC5              mov al,ch
0000C3BE  EE                out dx,al
0000C3BF  E6EB              out 0xeb,al
0000C3C1  58                pop ax
0000C3C2  BA0351            mov dx,0x5103
0000C3C5  EE                out dx,al
0000C3C6  E6EB              out 0xeb,al
0000C3C8  BA0051            mov dx,0x5100
0000C3CB  B007              mov al,0x7
0000C3CD  EE                out dx,al
0000C3CE  E82F00            call 0xc400
0000C3D1  BA0451            mov dx,0x5104
0000C3D4  EC                in al,dx
0000C3D5  59                pop cx
0000C3D6  C3                ret

0000C3D7  51                push cx            ;potential smbus
0000C3D8  50                push ax
0000C3D9  51                push cx
0000C3DA  BA0251            mov dx,0x5102
0000C3DD  8AC5              mov al,ch
0000C3DF  EE                out dx,al
0000C3E0  E6EB              out 0xeb,al
0000C3E2  58                pop ax
0000C3E3  BA0351            mov dx,0x5103
0000C3E6  EE                out dx,al
0000C3E7  E6EB              out 0xeb,al
0000C3E9  58                pop ax
0000C3EA  BA0451            mov dx,0x5104
0000C3ED  EE                out dx,al
0000C3EE  E6EB              out 0xeb,al
0000C3F0  BA0051            mov dx,0x5100
0000C3F3  B006              mov al,0x6
0000C3F5  EE                out dx,al
0000C3F6  E80700            call 0xc400
0000C3F9  59                pop cx
0000C3FA  C3                ret

0000C3FB  87DB              xchg bx,bx                ;more smbus maybe
0000C3FD  87DB              xchg bx,bx
0000C3FF  90                nop
0000C400  51                push cx
0000C401  BA0151            mov dx,0x5101
0000C404  F8                clc
0000C405  B90004            mov cx,0x400
0000C408  EC                in al,dx
0000C409  51                push cx
0000C40A  B90500            mov cx,0x5
0000C40D  E6EB              out 0xeb,al
0000C40F  E2FC              loop 0xc40d
0000C411  59                pop cx
0000C412  A880              test al,0x80
0000C414  0F850500          jnz near 0xc41d
0000C418  E2EE              loop 0xc408
0000C41A  EB09              jmp short 0xc425
0000C41C  90                nop
0000C41D  241F              and al,0x1f
0000C41F  0AC0              or al,al
0000C421  0F840300          jz near 0xc428
0000C425  B0FF              mov al,0xff
0000C427  F9                stc
0000C428  59                pop cx
0000C429  C3                ret

0000C42A  51                push cx              ;looks like smbus
0000C42B  51                push cx
0000C42C  BA0250            mov dx,0x5002
0000C42F  8AC5              mov al,ch
0000C431  EE                out dx,al
0000C432  E6EB              out 0xeb,al
0000C434  58                pop ax
0000C435  BA0350            mov dx,0x5003
0000C438  EE                out dx,al
0000C439  E6EB              out 0xeb,al
0000C43B  BA0050            mov dx,0x5000
0000C43E  B007              mov al,0x7
0000C440  EE                out dx,al
0000C441  E8EE00            call 0xc532
0000C444  BA0450            mov dx,0x5004
0000C447  EC                in al,dx
0000C448  59                pop cx
0000C449  C3                ret

0000C44A  51                push cx           ;again looks like smbus
0000C44B  BA0250            mov dx,0x5002
0000C44E  8AC5              mov al,ch
0000C450  EE                out dx,al
0000C451  E6EB              out 0xeb,al
0000C453  BA0050            mov dx,0x5000
0000C456  B005              mov al,0x5
0000C458  EE                out dx,al
0000C459  E8D600            call 0xc532
0000C45C  BA0450            mov dx,0x5004
0000C45F  EC                in al,dx
0000C460  59                pop cx
0000C461  C3                ret

Skip ahead a little bit...

0000C4BD  0002              add [bp+si],al          ;looks like smbus
0000C4BF  0407              add al,0x7
0000C4C1  0809              or [bx+di],cl
0000C4C3  32FA              xor bh,dl
0000C4C5  FB                sti
0000C4C6  FC                cld
0000C4C7  FF5150            call near [bx+di+0x50]
0000C4CA  51                push cx
0000C4CB  BA0250            mov dx,0x5002
0000C4CE  8AC5              mov al,ch
0000C4D0  EE                out dx,al
0000C4D1  E6EB              out 0xeb,al
0000C4D3  58                pop ax
0000C4D4  BA0350            mov dx,0x5003
0000C4D7  EE                out dx,al
0000C4D8  E6EB              out 0xeb,al
0000C4DA  58                pop ax
0000C4DB  BA0450            mov dx,0x5004
0000C4DE  EE                out dx,al
0000C4DF  E6EB              out 0xeb,al
0000C4E1  BA0050            mov dx,0x5000
0000C4E4  B006              mov al,0x6
0000C4E6  EE                out dx,al
0000C4E7  E84800            call 0xc532
0000C4EA  59                pop cx
0000C4EB  C3                ret

0000C4EC  51                push cx                     ;looks like smbus
0000C4ED  51                push cx
0000C4EE  BA0250            mov dx,0x5002
0000C4F1  8AC5              mov al,ch
0000C4F3  EE                out dx,al
0000C4F4  E6EB              out 0xeb,al
0000C4F6  58                pop ax
0000C4F7  BA0350            mov dx,0x5003
0000C4FA  EE                out dx,al
0000C4FB  E6EB              out 0xeb,al
0000C4FD  BA0050            mov dx,0x5000
0000C500  B009              mov al,0x9
0000C502  EE                out dx,al
0000C503  E82C00            call 0xc532
0000C506  BA0450            mov dx,0x5004
0000C509  ED                in ax,dx
0000C50A  59                pop cx
0000C50B  C3                ret

0000C50C  51                push cx           ;looks like smbus
0000C50D  50                push ax
0000C50E  51                push cx
0000C50F  BA0250            mov dx,0x5002
0000C512  8AC5              mov al,ch
0000C514  EE                out dx,al
0000C515  E6EB              out 0xeb,al
0000C517  58                pop ax
0000C518  BA0350            mov dx,0x5003
0000C51B  EE                out dx,al
0000C51C  E6EB              out 0xeb,al
0000C51E  58                pop ax
0000C51F  BA0450            mov dx,0x5004
0000C522  EF                out dx,ax
0000C523  E6EB              out 0xeb,al
0000C525  BA0050            mov dx,0x5000
0000C528  B008              mov al,0x8
0000C52A  EE                out dx,al
0000C52B  E6EB              out 0xeb,al
0000C52D  E80200            call 0xc532
0000C530  59                pop cx
0000C531  C3                ret

0000C532  51                push cx                       ;looks like smbus
0000C533  BA0150            mov dx,0x5001
0000C536  F8                clc
0000C537  B90001            mov cx,0x100
0000C53A  EC                in al,dx
0000C53B  E6EB              out 0xeb,al
0000C53D  A880              test al,0x80
0000C53F  0F850500          jnz near 0xc548
0000C543  E2F5              loop 0xc53a
0000C545  EB09              jmp short 0xc550
0000C547  90                nop
0000C548  241F              and al,0x1f
0000C54A  0AC0              or al,al
0000C54C  0F840300          jz near 0xc553
0000C550  B0FF              mov al,0xff
0000C552  F9                stc
0000C553  59                pop cx
0000C554  C3                ret
    


As you can see this is the 1st segment.
Probably 0xE000 or something, code that is gone from the 1st meg by the time you boot into dos.

It was right under some unkown sip/bui loading code that ties in with XGROUP (awdext).


It looked very simuler to me so I commented it in the txt's I have to the side for study (I map functions then replace the defines in my src with the actual code, using the old awd src to help guide me).


It's not 100% clear.
One thing does stand out:

0000C41A EB09 jmp short 0xc425
0000C425 B0FF mov al,0xff

Maybe, guessing here, that could be the value I'm getting with my current code.
I dn, it's a wild guess.


I have to map the few ports that are there, 0x500x.
And check out the jmps to see if I can figuer out what function is which.
Then check for calls to these functions to see if I can find how to use them.

Smile

I'll take that task on later on this afternoon or something.
Post 14 May 2009, 14:16
View user's profile Send private message Reply with quote
NEOAethyr



Joined: 20 Aug 2007
Posts: 19
NEOAethyr
Yestersday or this morning I forget (I was up for 24hrs before I went to sleep this afternoon..).

I noticed this when looking t see if I could actuallly map the functions of my bios to an actual name of function from leaked src code either from award or nvidia:

Code:
0000C3FB  87DB              xchg bx,bx            ;more smbus maybe, [CS_Chk_SMBus_READY] ???
0000C3FD  87DB              xchg bx,bx
0000C3FF  90                nop
0000C400  51                push cx
0000C401  BA0151            mov dx,0x5101
0000C404  F8                clc
0000C405  B90004            mov cx,0x400
0000C408  EC                in al,dx
0000C409  51                push cx
0000C40A  B90500            mov cx,0x5
0000C40D  E6EB              out 0xeb,al
0000C40F  E2FC              loop 0xc40d
0000C411  59                pop cx
0000C412  A880              test al,0x80
0000C414  0F850500          jnz near 0xc41d
0000C418  E2EE              loop 0xc408
0000C41A  EB09              jmp short 0xc425
0000C41C  90                nop
0000C41D  241F              and al,0x1f
0000C41F  0AC0              or al,al
0000C421  0F840300          jz near 0xc428
0000C425  B0FF              mov al,0xff
0000C427  F9                stc
0000C428  59                pop cx
0000C429  C3                ret
    


I do remmeber there was another, but less likely, possible match in the few amount of functions I found in my bios so far.
But I didn't lable it so whatever I guess.

Again tyhe nvidia src ported to asm for that function:

Code:
;This is the exact copy from chipboot.asm
;Chk_SMBus_READY code in chipboot.asm will not exist anymore after system boot to OS.
;This is used only for SMM mode.
;Input:            None
;Output:    Carry set means error, carry clear means ready.
CS_Chk_SMBus_READY:
push dx
push cx
push ax
mov dx, SMBUS_PORT2 + 0x01       ;Status port
clc
mov cx, 0x2000
CS_Chk_I2C_OK:
NEWIODELAY
in al, dx                  ;get status
or al, al                        ;N18
jz CS_Chk_I2C_OK                ;not ready
test al, 0x80                     ;is finished
jnz CS_Clear_final
test al, 0x1F
jz CS_Clear_final
and al, 0x1F
cmp al, 0x1A                        ;SMBus busy?
jne CS_SMBus_Err
;out dx, al                 ;clear status
loop CS_Chk_I2C_OK
CS_SMBus_Err:
stc
CS_Clear_final:
out dx, al                    ;clear status
pop ax
pop cx
pop dx
ret
    


Now for the copy in chipboot.asm that we aren't suppose to have either, but note this copy is far far older then the above 2:

Code:
Chk_SMBus_READY  Proc    near
                
            mov     dx,SMBus_Port + 0;status port
               clc
         mov     cx,0800h
Chk_I2c_OK:
         in      al,dx           ;get status
         NEWIODELAY
          out     dx,al           ;clear status
               NEWIODELAY

              test    al, 02H         ;termination of command ?
           jnz     short Clear_final

               and     al, NOT 40H     ;mask INUSE bit ;R06
                or      al,al           ;status OK ?
                jz      short Clear_final

               test    al,04h          ;device error
               jnz     short SMBus_Err

         loop    short Chk_I2c_OK
    ;SMbus error due to timeout
SMBus_Err:

           stc
         ret
Clear_final:
             clc
         ret
Chk_SMBus_READY  endp
    


That was all of the work I did at that time.

Just a few mins ago I did some more work.
I knew I needed some port names to go by if I was going to have any hope of knowing what ports where what in my bios'es code.
I would need to have a grasp of that when looking at the code to see if I could decode what it was doing.
If I had an idea of what was going on, I could note the simuler code in the older/leaked functions.

So far this is all I've done:

Code:
;NVIDIA_SMB_IO_BASE dw ?                            ;0x5000?
;NVIDIA_SMB_PRTCL   dw NVIDIA_SMB_IO_BASE           ;Protocol, PEC
;XBOX_SMB_IO_BASE     dw 0xC000

;NVIDIA_SMB_STS                dw (NVIDIA_SMB_IO_BASE + 0x01)  ;0x5001?, Status
;XBOX_SMB_GLOBAL_ENABLE     dw (XBOX_SMB_IO_BASE + 0x02)    ;0xC002

;NVIDIA_SMB_ADDR dw (NVIDIA_SMB_PRTCL + 0x02)    ;0x5002?, Address
;XBOX_SMB_HOST_ADDRESS     dw (XBOX_SMB_IO_BASE + 0x04)    ;0xC004

;NVIDIA_SMB_CMD          dw (NVIDIA_SMB_PRTCL + 0x03)    ;0x5003?, Command
;XBOX_SMB_HOST_COMMAND     dw (XBOX_SMB_IO_BASE + 0x08)    ;0xC008

;NVIDIA_SMB_DATA dw (NVIDIA_SMB_PRTCL + 0x04)    ;0x5004?, 32 Data registers
;XBOX_SMB_HOST_DATA      dw (XBOX_SMB_IO_BASE + 0x06)    ;0xC006

;generally nv vs. xbox port = 1:2 ratio
;excluding data and cmd, which still follow the 2:1 ratio but are swapped
;Status and GLOBAL_ENABLE I'm unsure if they are one and the same though
;Both nv and the xbox equal in the amount of ports defined (nasmx inc's and linux nv smbus drivers)

;Now I must study the actual usage of those ports on all sides, to see if they follow the same cmd routine
    


Like the last comment says, I must see if when my bios uses what looks to be the same ports with the same cmds, regardless of how it goes about it.

If so then I would have an ensentive to look for code that calls those functions.
Afterwards checking to see what those new found regions of code might be req'ing.

Something as simple as checking for rated cas at a certain fsb, likely with some buggy cmos cleared flag checking.
Ie the 3 cas offsets in the spd, or by cmos fsb/cas.
Checking for code that also calls some of the more odd cmos checking code (multible fast cmos loop checking functions that you can plug values into and that alot of code calls that I still don't know what does (Ie I have allmost all bios setup cmos related code mapped allready so...)).
Something as simple as that is all it would take for me to find the older functions from the award bios and map them in there full from on the newest of bios'es (pretty much anyways).

You never know, sometimes you can find something, and sometimes you can't find any anything or even clues, or sometimes just one clue or so but nothing to go by to dig deaper with (missing seg info's, etc).
^^

I'll figuer it out, even if I have to double back to POST.
I've got most of the post tables mapped, with there original post function names.
If I have to see if anyone them have the potential somewhere to use the smbus, I will.
I should beable to find the code I'm looking for.
It's gotta give the secrets up somewhere.


Edit:
Just came up with another reason I want this.

If I figuer this out I'm sure I won't find the cmos reloaded code right away, if not for a long time... who knows.
My board has an extra 64k cmos chip on it, I have the datasheet for the darn thing...
The idea was to use a portion of it for extra cmos and either forgot portions of the bios menu setup code for it's stuff and or include another debug menu which I ready have going and is using cmos for it's exit type (ret, ret and req esc key seq, or ret by bootstrapping the loader thingy and bypassing dmi and "extended like" (whatever you call them, still boots raid types and such though) vector types like network 2nd init pxe's.)

Boy that was long winded..., been smoking down a litle sorry..
Anyways the spd, the 2nd half goes unused at least from sdram to ddr1.
Never checked into ddr2 or dr3 types of spds...

That's ruffly 127bytes of info that is allways static unless you use an unstable spd program like thaiphoon burner.
It could be used as a debug cmos for sure, 100% complete too since the bios doesn't use the 2nd half for it's menu settings ever.
The 2nd half is scratch used during post and etc in some wacky ways, completely unusable becuase unlike some dynamic cmos offsets in the 1st half, the previous values read at startup aren't put back after scratch use.
And they can be destroyed quick quickly, very likely before your check function and apply setting gets to it.

It's not the most of ideal things.
Even if you redid the code on your board to ensure the bios could correctly boot a dead mem stick, other board's would still suffer.
So if at anytime you had a major corruption of the spd via this new debug cmos code or hand setting of it, well, it would not go to well with general users.

But it could help as a baises to unlock dead boards.
Preflash a bios chip with custom bui's and sip tables.
Flash a mem stick spd with a value set for such.
And try to post a dead board with diff tables, hand picking them forcing them into play.
Ie perhaps force errata which I have proven to exist after certain cleared cmos'es.
Or force cmd rate knowing at next boot the bios is dead because of the buggy nvidia cmd rate cmos scanning code (normally it's forced one way or another, if you enable the code and give it a modules that allways forces a certain cmd rate, it will die on 2nd boot when you write a diff value then running value for the cmos cmd rate offset).

Mainly it would allow me to test sip/bui tables at a new level.
onlying me to modfiy values of the tables in the bios menu it's self and seeing the results in memtest and such on diff reboots with quickenss and ease of a bios menu setting.
Making way for future settings, ones that are deemed most important in stability and speed of the cpu timings and bus timings.
Etc etc.

Smile
D@mnit give me it now lol, I wish, ahh someday sooner or later.
Laters Smile.


Last edited by NEOAethyr on 16 May 2009, 07:37; edited 1 time in total
Post 16 May 2009, 07:17
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17658
Location: In your JS exploiting you and your system
revolution
NEOAethyr: You had better hope your mobo doesn't ever go faulty or get out of date, because if it does you will have to do this work all over again with a new mobo and different hardware/ports/everything.
Post 16 May 2009, 07:30
View user's profile Send private message Visit poster's website Reply with quote
NEOAethyr



Joined: 20 Aug 2007
Posts: 19
NEOAethyr
It's ok, I've got a few bios chips at hand some preflashed just incase.
And multible sticks of memory I can use to recover the dead sticks with if need be.

All stuff I've had to use and do before so it's all good Very Happy.

I'm used to killing me board's Wink.
So I'm used to dealing with it and getting them running again on my own.

Oh and btw I'm getting a new board this comming month.
For my quad core and stuffs.
I got the data sheet for the new one's south bridge and smbus allready.
The sb600.
I also got enrolled in amd's dev program a feww days ago and got access to that data.
Still waiting on the ok for nvidia dev program...

I've got 3 nf2's.
A few via's, including an abit 754.
Getting a 790fx this next month.

The new one will need an extra bios chip, it's twice the size as the ones I have now.
For recovery, I can't work with that one's bios until I get one.

Also heard stories about how smbus access, in the wrong way, can kill newer boards, with some able to recover, and some never able to.
So I will have to know what I'm doing smbus wise on that board, and I willk have to take it easy.
I won't mess with smbus on that one for some time.
Post 16 May 2009, 07:40
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.