1# HP Laptops with KBC1126 Embedded Controller 2 3This document is about HP EliteBook series laptops up to Ivy Bridge era 4which use SMSC KBC1126 as embedded controller. 5 6SMSC KBC1126 (and older similar chips like KBC1098) has been used in 7HP EliteBooks for many generations. BIOS and EC firmware share an SPI 8flash chip in these laptops, so we need to put firmware blobs for the 9EC to the coreboot image. 10 11## EC firmware extraction and coreboot building 12 13The following document takes EliteBook 2760p as an example. 14 15First, you need to extract the blobs needed by EC firmware using util/kbc1126. 16You can extract them from your backup firmware image, or firmware update 17provided by HP with [unar] as follows: 18 19```bash 20wget https://ftp.hp.com/pub/softpaq/sp79501-80000/sp79710.exe 21unar sp79710.exe 22${COREBOOT_DIR}/util/kbc1126/kbc1126_ec_dump sp79710/Rompaq/68SOU.BIN 23mv 68SOU.BIN.fw1 ${COREBOOT_DIR}/2760p-fw1.bin 24mv 68SOU.BIN.fw2 ${COREBOOT_DIR}/2760p-fw2.bin 25``` 26 27When you config coreboot, select: 28 29```text 30Chipset ---> 31 [*] Add firmware images for KBC1126 EC 32 (2760p-fw1.bin) KBC1126 firmware #1 path and filename 33 (2760p-fw2.bin) KBC1126 filename #2 path and filename 34``` 35 36## Porting guide for HP laptops with KBC1126 37 38To port coreboot to an HP laptop with KBC1126, you need to do the 39following: 40 41- select Kconfig option `EC_HP_KBC1126` 42- select Kconfig option `SUPERIO_SMSC_LPC47N217` if there is LPC47n217 43 Super I/O, usually in EliteBook 8000 series, which can be used for 44 debugging via serial port 45- initialize EC and Super I/O in romstage 46- add EC and Super I/O support to devicetree.cb 47 48To get the related values for EC in devicetree.cb, you need to extract the EFI 49module EcThermalInit from the vendor UEFI firmware with [UEFITool]. Usually, 50`ec_data_port`, `ec_cmd_port` and `ec_ctrl_reg` has the following values: 51 52- For EliteBook xx60 series: 0x60, 0x64, 0xca 53- For EliteBook xx70 series: 0x62, 0x66, 0x81 54 55You can use [radare2] and the following [r2pipe] Python script to find 56these values from the EcThermalInit EFI module: 57 58```python 59#!/usr/bin/env python 60 61# install radare2 and use `pip3 install --user r2pipe` to install r2pipe 62 63import r2pipe 64import sys 65 66if len(sys.argv) < 2: 67 fn = "ecthermalinit.efi" 68else: 69 fn = sys.argv[1] 70 71r2 = r2pipe.open(fn) 72r2.cmd("aa") 73entryf = r2.cmdj("pdfj") 74 75for insn in entryf["ops"]: 76 if "lea r8" in insn["opcode"]: 77 _callback = insn["ptr"] 78 break 79 80r2.cmd("af @ {}".format(_callback)) 81callbackf_insns = r2.cmdj("pdfj @ {}".format(_callback))["ops"] 82 83def find_port(addr): 84 ops = r2.cmdj("pdfj @ {}".format(addr))["ops"] 85 for insn in ops: 86 if "lea r8d" in insn["opcode"]: 87 return insn["ptr"] 88 89ctrl_reg_found = False 90 91for i in range(0, len(callbackf_insns)): 92 if not ctrl_reg_found and "mov cl" in callbackf_insns[i]["opcode"]: 93 ctrl_reg_found = True 94 ctrl_reg = callbackf_insns[i]["ptr"] 95 print("ec_ctrl_reg = 0x%02x" % ctrl_reg) 96 cmd_port = find_port(callbackf_insns[i+1]["jump"]) 97 data_port = find_port(callbackf_insns[i+3]["jump"]) 98 print("ec_cmd_port = 0x%02x\nec_data_port = 0x%02x" % (cmd_port, data_port)) 99 100 if "mov bl" in callbackf_insns[i]["opcode"]: 101 ctrl_value = callbackf_insns[i]["ptr"] 102 print("ec_fan_ctrl_value = 0x%02x" % ctrl_value) 103``` 104 105 106[unar]: https://theunarchiver.com/command-line 107[UEFITool]: https://github.com/LongSoft/UEFITool 108[radare2]: https://radare.org/ 109[r2pipe]: https://github.com/radare/radare2-r2pipe 110