/ util / superiotool / amd.c
amd.c
  1  /* SPDX-License-Identifier: GPL-2.0-or-later */
  2  
  3  #include "superiotool.h"
  4  
  5  #define DEVICE_ID_REG		0x20
  6  #define DEVICE_REV_REG		0x21
  7  
  8  static const struct superio_registers reg_table[] = {
  9  	{0xb7, "SB7xx", {
 10  		{NOLDN, NULL,
 11  			{0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x28,0x29,0x2a,
 12  			 0x2b,0x2c,0x2e, 0x2f, EOT},
 13  			 {NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}},
 14  		{0x3, "EC channel 0",
 15  			{0x30,0x60,0x61, EOT},
 16  			 {NANA,NANA,NANA,EOT}},
 17  		{0x5, "Irda",
 18  			{0x30,0x60,0x61,0x70, EOT},
 19  			 {NANA,NANA,NANA,NANA,EOT}},
 20  		{0x7, "Keyboard Controller",
 21  			{0x30, EOT},
 22  			 {NANA,EOT}},
 23  		{0x9, "Mailbox",
 24  			{0x30,0x60,0x61, EOT},
 25  			{NANA,NANA,NANA,EOT}},
 26  		{EOT}}},
 27  	{0xb8, "SB8xx", {
 28  		{NOLDN, NULL,
 29  			{0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x28,0x29,0x2a,
 30  			 0x2b,0x2c,0x2e, 0x2f, EOT},
 31  			 {NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}},
 32  		{0x3, "EC channel 0",
 33  			{0x30,0x60,0x61, EOT},
 34  			 {NANA,NANA,NANA,EOT}},
 35  		{0x5, "Irda",
 36  			{0x30,0x60,0x61,0x70, EOT},
 37  			 {NANA,NANA,NANA,NANA,EOT}},
 38  		{0x7, "Keyboard Controller",
 39  			{0x30, EOT},
 40  			 {NANA,EOT}},
 41  		{0x9, "Mailbox",
 42  			{0x30,0x60,0x61, EOT},
 43  			{NANA,NANA,NANA,EOT}},
 44  		{EOT}}},
 45  	{EOT}
 46  };
 47  
 48  /* same as serverengines */
 49  static void enter_conf_mode_ec(uint16_t port)
 50  {
 51  	OUTB(0x5a, port);
 52  }
 53  
 54  static void exit_conf_mode_ec(uint16_t port)
 55  {
 56  	OUTB(0xa5, port);
 57  }
 58  
 59  uint16_t detect_ec(void)
 60  {
 61  	uint16_t ec_port;
 62  	struct pci_dev *dev;
 63  
 64  	dev = pci_dev_find(0x1002, 0x439d);
 65  
 66  	if (!dev) {
 67  		return 0;
 68  	}
 69  
 70  	/* is EC disabled ? */
 71  	if (!(pci_read_byte(dev, 0x40) & (1 << 7)))
 72  		return 0;
 73  
 74  	ec_port = pci_read_word(dev, 0xa4);
 75  
 76  	if (!(ec_port & 0x1))
 77  		return 0;
 78  
 79  	ec_port &= ~0x1;
 80  
 81  	return ec_port;
 82  }
 83  
 84  void probe_idregs_amd(uint16_t port)
 85  {
 86  	uint8_t rev, devid;
 87  
 88  	probing_for("AMD EC", "", port);
 89  
 90  	if (!(port = detect_ec()))
 91  		return;
 92  
 93  	enter_conf_mode_ec(port);
 94  
 95  	devid = regval(port, DEVICE_ID_REG);
 96  	rev = regval(port, DEVICE_REV_REG);
 97  
 98  	if (superio_unknown(reg_table, devid)) {
 99  		if (verbose)
100  			printf(NOTFOUND "id=0x%02x, rev=0x%02x\n", devid, rev);
101  		exit_conf_mode_ec(port);
102  		return;
103  	}
104  
105  	printf("Found AMD EC %s (id=0x%02x, rev=0x%02x) at 0x%x\n",
106  	       get_superio_name(reg_table, devid), devid, rev, port);
107  	chip_found = 1;
108  
109  	dump_superio("AMD EC", reg_table, port, devid, LDN_SEL);
110  
111  	exit_conf_mode_ec(port);
112  }
113  
114  void print_amd_chips(void)
115  {
116  	print_vendor_chips("AMD EC", reg_table);
117  }