Name Date Size #Lines LOC

..--

bifurcation/H--177112

subprojects/H--75

test/H--2,5011,695

.clang-formatH A D01-Feb-20253.7 KiB137135

.gitignoreH A D20-Sep-202157 54

.lcovrcH A D13-Mar-201980 43

LICENSEH A D17-Sep-201811.1 KiB202169

MAINTAINERSH A D19-May-20221.9 KiB4735

OWNERSH A D01-Feb-20251.6 KiB4944

README.mdH A D02-Jul-202522.2 KiB582403

bios_setting.cppH A D19-Aug-20243.9 KiB12895

bios_setting.hppH A D19-Aug-20241.1 KiB4219

bm_instance.cppH A D16-Aug-20242.1 KiB7750

bm_instance.hppH A D03-May-2024936 3615

bmc_mode.cppH A D19-May-20231.1 KiB4626

bmc_mode.hppH A D19-May-2023855 3412

bmc_mode_enum.hppH A D11-Jul-20231 KiB3819

cable.cppH A D25-Oct-20233 KiB10057

cable.hppH A D19-May-20231,022 4216

commands.hppH A D19-Aug-20242.7 KiB8036

cpld.cppH A D25-Oct-20232.3 KiB8245

cpld.hppH A D19-May-20231 KiB4420

entity_name.cppH A D16-Aug-20242.4 KiB9260

entity_name.hppH A D19-May-20231.1 KiB4217

errors.hppH A D19-May-20231.2 KiB5428

eth.cppH A D17-Jun-20242.1 KiB7143

eth.hppH A D19-May-20231.2 KiB4818

file_system_wrapper.cppH A D11-Jul-20231.2 KiB4525

file_system_wrapper.hppH A D11-Jul-20231.9 KiB6519

file_system_wrapper_impl.hppH A D11-Jul-20231 KiB3617

flash_size.cppH A D16-Aug-20241.4 KiB5534

flash_size.hppH A D19-May-2023936 3916

gbmc-host-poweroff.targetH A D16-Jun-202138 32

google_accel_oob.cppH A D30-Jan-202410.3 KiB341254

google_accel_oob.hppH A D30-Jan-20241.4 KiB4620

handler.cppH A D01-Feb-202524.4 KiB815671

handler.hppH A D01-Feb-20257.5 KiB24855

handler_impl.hppH A D21-Jul-20255.1 KiB14197

host_power_off.cppH A D25-Oct-20231.6 KiB6037

host_power_off.hppH A D19-May-20231 KiB4318

ipmi.cppH A D19-Aug-20243.5 KiB11088

ipmi.hppH A D19-May-20231,020 3815

linux_boot_done.cppH A D29-Jun-20231.2 KiB4726

linux_boot_done.hppH A D29-Jun-2023858 3412

machine_name.cppH A D25-Oct-20231.8 KiB6945

machine_name.hppH A D19-May-2023983 4016

main.cppH A D16-Aug-20241.6 KiB6439

meson.buildH A D07-Aug-20252.1 KiB9078

meson.optionsH A D01-Feb-2025498 2019

pcie_bifurcation.cppH A D01-Nov-20232.1 KiB7648

pcie_bifurcation.hppH A D10-Oct-2021893 3514

pcie_i2c.cppH A D02-Jul-20253.5 KiB11370

pcie_i2c.hppH A D19-May-20231.3 KiB5223

psu.cppH A D25-Oct-20232 KiB7751

psu.hppH A D19-May-20231.2 KiB4619

util.cppH A D25-Oct-20234.3 KiB149104

util.hppH A D19-May-20231.4 KiB5515

README.md

1# google-ipmi-sys
2
3## Sys Commands (0x32)
4
5There are and will be a variety of sys specific commands.
6
7### Cablecheck - SubCommand 0x00
8
9The cablecheck command checks whether the BMC is seeing traffic between itself
10and the host's NIC. Sys specifies which if_name is expected to be connected. The
11BMC presently only checks traffic on the interface specified. There are now
12ethernet statistics available over IPMI, which can be checked directly in lieu
13of this.
14
15Request
16
17| Byte(s)  | Value          | Data                                          |
18| -------- | -------------- | --------------------------------------------- |
19| 0x00     | 0x00           | Subcommand                                    |
20| 0x01     | If_name length | Where you expect the cable, eth0 or eth1, etc |
21| 0x02 ... | The name       | The string, not null-terminated               |
22
23Response
24
25| Byte(s) | Value     | Data                    |
26| ------- | --------- | ----------------------- |
27| 0x00    | 0x00      | Subcommand              |
28| 0x01    | 0x00/0x01 | 0 for false, 1 for true |
29
30### CpldVersion - SubCommand 0x01
31
32Any CPLD on the system that can only be read directly via the BMC can have its
33version exported to Sys via the cpld version command.
34
35Request
36
37| Byte(s) | Value   | Data                                                            |
38| ------- | ------- | --------------------------------------------------------------- |
39| 0x00    | 0x01    | Subcommand                                                      |
40| 0x01    | CPLD ID | A one-byte identifier for the CPLD file to read, unsigned byte. |
41
42Response
43
44| Byte(s) | Value | Data                  |
45| ------- | ----- | --------------------- |
46| 0x00    | 0x01  | Subcommand            |
47| 0x01    | Major | Major version         |
48| 0x02    | Minor | Minor Version         |
49| 0x03    | Sub 1 | Third version number  |
50| 0x04    | Sub 2 | Fourth version number |
51
52**Per the above, if the version number doesn't fit in a byte it'll be cast to
53size.**
54
55### GetEthDevice - SubCommand 0x02
56
57The BMC itself must have hard-coded into the image, which ethernet device is
58connected to the host NIC. This is true also in the mapping of ethernet device
59to channel number. Alternatively, you can pass a specific interface name for
60channel lookup. The channel number is used to configure the ethernet device over
61IPMI, instead of the interface name. This is because we leverage the current
62IPMI command set to read and write the networking configuration. Sys can be
63programmed already to have this information in the board protobuf, however, this
64information -- can be read from the BMC over IPMI.
65
66Request
67
68| Byte(s) | Value   | Data                                               |
69| ------- | ------- | -------------------------------------------------- |
70| 0x00    | 0x02    | Subcommand                                         |
71| 0x01... | if_name | (optional) The interface name, not null-terminated |
72
73Response
74
75| Byte(s) | Value          | Data                                                                                                                        |
76| ------- | -------------- | --------------------------------------------------------------------------------------------------------------------------- |
77| 0x00    | 0x02           | Subcommand                                                                                                                  |
78| 0x01    | Channel number | The IPMI channel number for use with the network configuration commands (such as reading the MAC or IP address of the BMC). |
79| 0x02    | if_name length | The length of the if_name in bytes.                                                                                         |
80| 0x03... | if_name        | The interface name, not null-terminated                                                                                     |
81
82### DelayedHardReset - SubCommand 0x03
83
84Sys needs to be able to tell the BMC to reset the host but given a delay in
85seconds.
86
87Request
88
89| Byte(s)    | Value | Data                      |
90| ---------- | ----- | ------------------------- |
91| 0x00       | 0x03  | Subcommand                |
92| 0x01..0x04 |       | Seconds to delay (uint32) |
93
94Response
95
96| Byte(s) | Value | Data       |
97| ------- | ----- | ---------- |
98| 0x00    | 0x03  | Subcommand |
99
100## GetPCIeSlotsCount - SubCommand 0x04
101
102Sys can get the total number of PCIe slots from BMC using this command. When BMC
103receives this command, BMC can enumerate over all the PCIe slots and create a
104hashmap with all the available PCIe slot name - I2C bus number mappings. BMC can
105then send the total number of PCIe slots as part of this command response.
106
107Request
108
109| Byte(s) | Value | Data       |
110| ------- | ----- | ---------- |
111| 0x00    | 0x04  | Subcommand |
112
113Response
114
115| Byte(s) | Value                      | Data                       |
116| ------- | -------------------------- | -------------------------- |
117| 0x00    | 0x04                       | Subcommand                 |
118| 0x01    | Total number of PCIe slots | Total number of PCIe slots |
119
120## GetPCIeSlotI2cBusMapping - SubCommand 0x05
121
122If Sys gets N total slots as part of the above command, then Sys can send this
123command N times with Entry IDs ranging from 0 to N - 1. Say, Sys sends this
124command with Entry ID as 1, BMC can go and fetch the first PCIe slot name - I2C
125bus number mapping from the hashmap created above and then send the PCIe slot
126name and I2C bus number as part of the command response.
127
128Request
129
130| Byte(s) | Value    | Data                             |
131| ------- | -------- | -------------------------------- |
132| 0x00    | 0x05     | Subcommand                       |
133| 0x01    | Entry ID | Entry ID ranging from 0 to N - 1 |
134
135Response
136
137| Byte(s) | Value                 | Data                                                     |
138| ------- | --------------------- | -------------------------------------------------------- |
139| 0x00    | 0x05                  | Subcommand                                               |
140| 0x01    | I2C bus number        | The I2C bus number which is input to the above PCIe slot |
141| 0x02    | PCIe slot name length | The PCIe slot name length                                |
142| 0x03... | PCIe slot name        | The PCIe slot name without null terminator               |
143
144## GetEntityName - SubCommand 0x06
145
146Gsys can get the "Entity ID:Entity Instance" to Entity name mapping from BMC
147using this command. When BMC receives this command, BMC can check the related
148JSON file and then send the name for that particular entity as this command
149response.
150
151Request
152
153| Byte(s) | Value           | Data            |
154| ------- | --------------- | --------------- |
155| 0x00    | 0x06            | Subcommand      |
156| 0x01    | Entity ID       | Entity ID       |
157| 0x02    | Entity Instance | Entity Instance |
158
159Response
160
161| Byte(s)             | Value                      | Data                                |
162| ------------------- | -------------------------- | ----------------------------------- |
163| 0x00                | 0x06                       | Subcommand                          |
164| 0x01                | Entity name length (say N) | Entity name length                  |
165| 0x02...0x02 + N - 1 | Entity name                | Entity name without null terminator |
166
167## GetMachineName - SubCommand 0x07
168
169The BMC parses /etc/os-release for the OPENBMC_TARGET_MACHINE field and returns
170its value.
171
172Request
173
174| Byte(s) | Value | Data       |
175| ------- | ----- | ---------- |
176| 0x00    | 0x06  | Subcommand |
177
178Response
179
180| Byte(s)             | Value                     | Data                               |
181| ------------------- | ------------------------- | ---------------------------------- |
182| 0x00                | 0x06                      | Subcommand                         |
183| 0x01                | Model name length (say N) | Model name length                  |
184| 0x02...0x02 + N - 1 | Model name                | Model name without null terminator |
185
186## HardResetOnShutdown - SubCommand 0x08
187
188Tells the BMC to powercycle the next time the host shuts down.
189
190Request
191
192| Byte(s) | Value | Data       |
193| ------- | ----- | ---------- |
194| 0x00    | 0x08  | Subcommand |
195
196Response
197
198| Byte(s) | Value | Data       |
199| ------- | ----- | ---------- |
200| 0x00    | 0x08  | Subcommand |
201
202## GetFlashSize - SubCommand 0x09
203
204Request the physical size of the BMC flash.
205
206Request
207
208| Byte(s) | Value | Data       |
209| ------- | ----- | ---------- |
210| 0x00    | 0x09  | Subcommand |
211
212Response
213
214| Byte(s)     | Value      | Data       |
215| ----------- | ---------- | ---------- |
216| 0x00        | 0x09       | Subcommand |
217| 0x01...0x04 | Flash size | Flash size |
218
219## HostPowerOff - SubCommand 0x0A
220
221Sys command needs to be able to let the BMC knows host attempt S5 shutdown, it
222need power-off the Host gracefully and disable the watchdog with given time
223delay.
224
225Request
226
227| Byte(s)    | Value | Data                      |
228| ---------- | ----- | ------------------------- |
229| 0x00       | 0x0A  | Subcommand                |
230| 0x01..0x04 |       | Seconds to delay (uint32) |
231
232Response
233
234| Byte(s) | Value | Data       |
235| ------- | ----- | ---------- |
236| 0x00    | 0x0A  | Subcommand |
237
238## AccelOobDeviceCount - SubCommand 0x0B
239
240Query the number of available devices from the google-accel-oob service.
241
242If not enough data is proveded, `ipmi::ccReqDataLenInvalid` is returned.
243
244Request
245
246| Byte(s) | Value | Data       |
247| ------- | ----- | ---------- |
248| 0x00    | 0x0B  | Subcommand |
249
250Response
251
252| Byte(s)    | Value | Data                        |
253| ---------- | ----- | --------------------------- |
254| 0x00       | 0x0B  | Subcommand                  |
255| 0x01..0x04 |       | Number of devices available |
256
257## AccelOobDeviceName - SubCommand 0x0C
258
259Query the name of a single device from the google-accel-oob service.
260
261This name is used as the identifier for the AccelOobRead and AccelOobWrite
262commands.
263
264Index values start at zero and go up to (but don't include) the device count.
265
266The name of the device is exactly as it appears in DBus, except for the common
267"/com/google/customAccel/" prefix. This prefix is removed to reduce the size of
268the IPMI packet.
269
270DBus requires all element names to be non-empty strings of ASCII characters
271`[A-Z][a-z][0-9]\_`, separated by ASCII `/`. Therefore, all device names will be
272valid ASCII strings (1 byte/character).
273
274For convenience, the name string is followed by a single 0x00 (NULL terminator)
275byte which is not included as part of the length.
276
277The length field (byte 5) is the number of bytes in the name string (not
278including the trailing NULL terminator byte).
279
280The maximum length for any name is 43 bytes (not including the trailing NULL).
281
282If a name is longer than 43 bytes, `ipmi::ccReqDataTruncated` is returned. These
283names will not be usable in the rest of the API. Changing the name requires code
284changes to the `managed_acceld` service binary.
285
286If not enough data is proveded, `ipmi::ccReqDataLenInvalid` is returned.
287
288If a name does not begin with the expected "/com/google/customAccel/" prefix,
289`ipmi::ccInvalidCommand` is returned. This indicates a change in the DBus API
290for the google-accel-oob service that requires a matching code change in the
291handler.
292
293Request
294
295| Byte(s) | Value | Data               |
296| ------- | ----- | ------------------ |
297| 0x00    | 0x0C  | Subcommand         |
298| 0x05    |       | Length of the name |
299| 0x06..n |       | Name of the device |
300
301Response
302
303| Byte(s)    | Value | Data                |
304| ---------- | ----- | ------------------- |
305| 0x00       | 0x0C  | Subcommand          |
306| 0x01..0x04 |       | Index of the device |
307| 0x05       |       | Length of the name  |
308| 0x06..n    |       | Name of the device  |
309
310## AccelOobRead - SubCommand 0x0D
311
312Read a PCIe CSR from a device.
313
314Length is the length of the name, in bytes.
315
316The device name gets prepended with "/com/google/customAccel/" and sent to DBus.
317This string must **NOT** have a trailing NULL terminator.
318
319The token is an arbitrary byte that gets echoed back in the reply; it is not
320interpreted by the service at all. This is used to disambiguate identical
321requests so clients can check for lost transactions.
322
323Address is the 64b PCIe address to read from.
324
325Number of bytes is the size of the read, in bytes (max 8). The value is subject
326to hardware limitations (both PCIe and ASIC), so it will generally be 1, 2, 4,
327or 8.
328
329The register data is always returned in 8 bytes (uint64) in little Endian order.
330If fewer than than 8 bytes are read, the MSBs are padded with 0s.
331
332On success, the response ends with the data read as a single uint64.
333
334If the number of bytes requested would not fit in a single IPMI payload,
335`ipmi::ccRetBytesUnavailable` is returned.
336
337If not enough data is proveded, `ipmi::ccReqDataLenInvalid` is returned.
338
339Request
340
341| Byte(s)   | Value | Data                                           |
342| --------- | ----- | ---------------------------------------------- |
343| 0x00      | 0x0D  | Subcommand                                     |
344| 0x01      |       | Number of bytes in the device name             |
345| 0x02..n   |       | Name of the device (from `AccelOobDeviceName`) |
346| n+1       |       | Token                                          |
347| n+2..n+10 |       | Address                                        |
348| n+11      |       | Number of bytes                                |
349
350Response
351
352| Byte(s)    | Value | Data                                  |
353| ---------- | ----- | ------------------------------------- |
354| 0x00       | 0x0D  | Subcommand                            |
355| 0x01       |       | Number of bytes in the device name    |
356| 0x02..n    |       | Name of the device (no trailing NULL) |
357| n+1        |       | Token                                 |
358| n+2..n+10  |       | Address                               |
359| n+11       |       | Number of bytes                       |
360| n+12..n+20 |       | Data                                  |
361
362## AccelOobWrite - SubCommand 0x0E
363
364Write a PCIe CSR from a device.
365
366All parameters are identical to AccelOobRead (above). The only difference is the
367register data becomes an input parameter (in the Request) instead of an output
368value (in the Response).
369
370As with read, the register data must be 8 bytes (uint64) in little Endian order.
371If fewer than 8 bytes will be written, only the LSBs will be read and the the
372MSBs will be ignored.
373
374All fields returned in the Response are simply a copy of the Request.
375
376On success, `ipmi::ccSuccess` is returned.
377
378If not enough data is proveded, `ipmi::ccReqDataLenInvalid` is returned.
379
380Request
381
382| Byte(s)    | Value | Data                                           |
383| ---------- | ----- | ---------------------------------------------- |
384| 0x00       | 0x0D  | Subcommand                                     |
385| 0x01       |       | Number of bytes in the device name             |
386| 0x02..n    |       | Name of the device (from `AccelOobDeviceName`) |
387| n+1        |       | Token                                          |
388| n+2..n+10  |       | Address                                        |
389| n+11       |       | Number of bytes                                |
390| n+12..n+20 |       | Data                                           |
391
392Response
393
394| Byte(s)    | Value | Data                                  |
395| ---------- | ----- | ------------------------------------- |
396| 0x00       | 0x0D  | Subcommand                            |
397| 0x01       |       | Number of bytes in the device name    |
398| 0x02..n    |       | Name of the device (no trailing NULL) |
399| n+1        |       | Token                                 |
400| n+2..n+10  |       | Address                               |
401| n+11       |       | Number of bytes                       |
402| n+12..n+20 |       | Data                                  |
403
404## PCIe Bifurcation - SubCommand 0x0F
405
406Sys command to return the highest level of bifurcation for the target PCIe Slot.
407
408Request
409
410| Byte(s) | Value          | Data                 |
411| ------- | -------------- | -------------------- |
412| 0x00    | 0x0F           | Subcommand           |
413| 0x01    | PE slot number | Index of the PE slot |
414
415Response
416
417| Byte(s)            | Value             | Data                                                                              |
418| ------------------ | ----------------- | --------------------------------------------------------------------------------- |
419| 0x00               | 0x0F              | Subcommand                                                                        |
420| 0x01               | Config length (N) | Number of bytes needed for the bifurcation config                                 |
421| 0x02..0x02 + N - 1 | Lanes per device  | Each byte represents the number of lanes bonded together for each endpoint device |
422
423## GetBmcMode - SubCommand 0x10
424
425Request the operational mode of the BMC.
426
427Request
428
429| Byte(s) | Value | Data       |
430| ------- | ----- | ---------- |
431| 0x00    | 0x10  | Subcommand |
432
433Response
434
435| Byte(s) | Value            | Data                                                                                  |
436| ------- | ---------------- | ------------------------------------------------------------------------------------- |
437| 0x00    | 0x10             | Subcommand                                                                            |
438| 0x01    | Current BMC MODE | **0 -> Non Bare Metal Mode**<br>1 -> Bare Metal Mode<br>2 -> Bare Metal Cleaning Mode |
439
440## LinuxBootDone - SubCommand 0x11
441
442Notify the BMC that LinuxBoot is finished and will kexec into the OS
443momentarily.
444
445If in bare metal mode, the BMC will disable IPMI upon receiving this command, to
446protect against a malicious OS. For this reason, the BMC may not respond to this
447command.
448
449If not in bare metal mode, this command has no effect.
450
451Request
452
453| Byte(s) | Value | Data       |
454| ------- | ----- | ---------- |
455| 0x00    | 0x11  | Subcommand |
456
457Response (if applicable)
458
459| Byte(s) | Value | Data       |
460| ------- | ----- | ---------- |
461| 0x00    | 0x11  | Subcommand |
462
463## SysGetAccelVrSettings - SubCommand 0x15
464
465Get the accel's VR setting value for the given chip and settings ID
466
467Currently 6 settings are supported. [0] IdleMode [1] PowerBrake [2] Loadline [3]
468VoutMargin [4] VoutSetpoint [5] NominalTargetVout
469
470On success, the response contains 2 bytes containing the setting value.
471
472If not enough data is proveded, `ipmi::ccReqDataLenInvalid` is returned.
473
474Request
475
476| Byte(s) | Value | Data       |
477| ------- | ----- | ---------- |
478| 0x00    | 0x15  | Subcommand |
479| 0x01    |       | Chip ID    |
480| 0x02    |       | SettingsID |
481
482Response (if applicable)
483
484| Byte(s)    | Value | Data           |
485| ---------- | ----- | -------------- |
486| 0x00       | 0x15  | Subcommand     |
487| 0x01..0x02 | 0x15  | Settings Value |
488
489## SysSetAccelVrSettings - SubCommand 0x16
490
491Update the VR settings of a given accel device for a specific settings id.
492
493Currently 6 settings are supported. [0] IdleMode [1] PowerBrake [2] Loadline [3]
494VoutMargin [4] VoutSetpoint [5] NominalTargetVout
495
496The settings value parameter is a 2 byte value and is expected in little endian
497format
498
499On success, `ipmi::ccSuccess` is returned.
500
501If not enough data is proveded, `ipmi::ccReqDataLenInvalid` is returned.
502
503Request
504
505| Byte(s)    | Value | Data           |
506| ---------- | ----- | -------------- |
507| 0x00       | 0x16  | Subcommand     |
508| 0x01       |       | Chip ID        |
509| 0x02       |       | Settings ID    |
510| 0x03..0x04 | 0x16  | Settings Value |
511
512Response (if applicable)
513
514| Byte(s) | Value | Data       |
515| ------- | ----- | ---------- |
516| 0x00    | 0x16  | Subcommand |
517
518## GetBMInstanceProperty - SubCommand 0x17
519
520Read a BM instance property, specify the property to read following the enum.
521
522The response contains the length of the property string to read in bytes
523followed by the property string which does **NOT** have a NULL terminator.
524
525Request
526
527| Byte(s) | Value | Data                                                                                                                                 |
528| ------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------ |
529| 0x00    | 0x17  | Subcommand                                                                                                                           |
530| 0x01    |       | 0x0: AssetTag <br>0x1: BoardSerialNumber <br>0x2: Family <br>0x3: ProductName <br>0x4: SKU <br>0x5: SystemSerialNumber <br>0x6: UUID |
531
532Response
533
534| Byte(s)           | Value              | Data                                                             |
535| ----------------- | ------------------ | ---------------------------------------------------------------- |
536| 0x00              | 0x17               | Subcommand                                                       |
537| 0x01              | String Length (N)  | Number of bytes to read for property string - Size limited to 64 |
538| 0x2..0x02 + N - 1 | String of property | String, not null-terminated                                      |
539
540## ReadBiosSetting - SubCommand 0x18
541
542Read a BIOS setting, set at `/run/oem_bios_setting`.
543
544The response contains the length of the BIOS setting followed by the BIOS
545setting bytes read.
546
547Request
548
549| Byte(s) | Value | Data       |
550| ------- | ----- | ---------- |
551| 0x00    | 0x18  | Subcommand |
552
553Response
554
555| Byte(s)           | Value         | Data                                         |
556| ----------------- | ------------- | -------------------------------------------- |
557| 0x00              | 0x18          | Subcommand                                   |
558| 0x01              | Length (N)    | Number of payload bytes - Size limited to 64 |
559| 0x2..0x02 + N - 1 | Payload bytes | Payload bytes                                |
560
561## WriteBiosSetting - SubCommand 0x19
562
563Write a BIOS setting, set at `/run/oem_bios_setting`.
564
565The response contains the length of the BIOS setting followed by the BIOS
566setting bytes read.
567
568Request
569
570| Byte(s)           | Value         | Data                                         |
571| ----------------- | ------------- | -------------------------------------------- |
572| 0x00              | 0x19          | Subcommand                                   |
573| 0x01              | Length (N)    | Number of payload bytes - Size limited to 64 |
574| 0x2..0x02 + N - 1 | Payload bytes | Payload bytes                                |
575
576Response
577
578| Byte(s) | Value      | Data                                 |
579| ------- | ---------- | ------------------------------------ |
580| 0x00    | 0x19       | Subcommand                           |
581| 0x01    | Length (N) | Number of bytes successfully written |
582