marcan changed the topic of #asahi to: Asahi Linux: porting Linux to Apple Silicon macs | Not ready for end users / self contained install yet. Soon. | General project discussion | GitHub: https://alx.sh/g | Wiki: https://alx.sh/w | Topics: #asahi-dev #asahi-re #asahi-gpu #asahi-stream #asahi-offtopic | Keep things on topic | Logs: https://alx.sh/l/asahi
chengsun has quit [Quit: Quit]
joe[_]D has quit []
Dcow has joined #asahi
yuyichao_ has quit [Ping timeout: 480 seconds]
bmrgz has quit [Quit: Page closed]
chengsun has joined #asahi
<chengsun>
marcan: also confirming both brcmfmac patches work on rpi3b. Tested on 5.15.0-1-ARCH aarch64; Firmware: BCM43430/1 wl0: Mar 30 2021 01:12:21 version 7.45.98.118 (7d96287 CY) FWID 01-32059766
chengsun has quit [Quit: Quit]
chengsun has joined #asahi
Dcow has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Dcow has joined #asahi
jmr2 has joined #asahi
<jmr2>
You can put this firmware as working as well, still on RPi 4:
<jmr2>
brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM4345/6 wl0: Jan 4 2021 19:56:29 version 7.45.229 (617f1f5 CY) FWID 01-2dbd9d2e
<jmr2>
Tested by overwriting the current release (bullseye)'s firmware files with those from Legacy (buster).
<kode54>
marcan: I have three hubs. The one connected directly to the Mac mini is a 3.0 hub, optionally powered, and its topology shows that there's both a 3.0 and 2.0 hub attached directly to the system by it.
<kode54>
then a switchable 3.0 hub with its upstream ports connected to both that first hub, and to my Ryzen desktop that I mostly use headless
<kode54>
that also has both 3.0 and 2.0 topology, depending on what's plugged into it
<kode54>
then a 2.0 hub in my secondary monitor, connected to another port on the first one
<kode54>
the multi card reader, I can't tell if it's 2.0 or 1.0
<kode54>
it seems really slow, so it's probably a stinking 1.0 device
<kode54>
the only other reader I have on hand is a 5.25" bay mounted thing that plugs into 3.0, and it's so buggy that it frequently disconnects itself at random
darkapex1 has joined #asahi
darkapex has quit [Ping timeout: 480 seconds]
DarkShadow44 has joined #asahi
<marcan>
hm, I think 3 hubs should work
chadmed has joined #asahi
c10l0 has joined #asahi
yuyichao has joined #asahi
c10l has quit [Ping timeout: 480 seconds]
yuyichao has quit []
yuyichao has joined #asahi
c10l0 has quit []
c10l0 has joined #asahi
c10l0 is now known as c10l
yuyichao has quit [Quit: Konversation terminated!]
phiologe has quit [Ping timeout: 480 seconds]
Dcow has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Dcow has joined #asahi
Dcow has quit []
yuyichao has joined #asahi
yuyichao has quit []
yuyichao has joined #asahi
marvin24 has joined #asahi
marvin24_ has quit [Ping timeout: 480 seconds]
darkapex2 has joined #asahi
darkapex1 has quit [Ping timeout: 480 seconds]
<fionera[m]>
heh I think I locked me out of my recovery. I recreated my Admin User but with a different username and now I cant authorize commands in 1TR
<fionera[m]>
I get a "Boot policy error: not a valid admin user for the volume at <>". Gonna recreate the apfs containers for the linux install lets see if it fixes it
Dcow has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<fionera[m]>
ok works again :)
Dcow has joined #asahi
Dcow_ has quit [Ping timeout: 480 seconds]
sailorek1234 has joined #asahi
bps2 has joined #asahi
<marcan>
fionera[m]: to fix that you need to copy a certain file in the preboot partition
<marcan>
yes, this is somewhat fragile, because we're basically cloning the user references that macOS has
<marcan>
eventually, once we support the SEP in Linux, we should do something on first boot to prompt the user to create new SEP-backed credentials, and ideally switch the Preboot stuff to point to that
<marcan>
I should probably also do something like stash some metadata into our stubs, like the VGID of the macOS that the users were cloned from, so that future invocations can refer to it and update that file if necessary
<marcan>
just pushed the wifi stuff to wifi/take1. It's on top of the current asahi branch (with one rebase/fixup applied).
<marcan>
it should add support for all the chips (including the T2 ones), but firmware selection for T2 machines isn't properly done yet.
bps2 has joined #asahi
<marcan>
you need to get the firmware manually from macOS for now; from asahi-installer: cd src; python -m firmware.wifi /usr/share/firmware/wifi firmware.tar
<marcan>
I did a ~full GUI test on j314s and a smoke test (ifup, no config) on j274
<marcan>
if I get a few reports that it works properly (and reliably), I'll push it to a future asahi rebase along with other updates
<j`ey>
marcan: brcmf_pcie_copy_mem_todev is used for copying the fw to the bcrm?
<j`ey>
brcm
<marcan>
28 patches...
<marcan>
j`ey: yes
<marcan>
so it's worth optimizing
<marcan>
it actually spends a noticeable amount of time doing that
<marcan>
still need to do a review pass to make sure I didn't screw up the commit splitting, but to a first approximation it should be a sane patch series
bps2 has quit [Ping timeout: 480 seconds]
<zsxh>
Is that branch good to try out?
<j`ey>
marcan: in e2b4b1ea44b3d6be10bcc3fc28b8467e081d0da6, sizeof(const char *) * 7, Im guessing 7 is the max_num_dimensions?
<marcan>
number of elements in the array that get set later plus one (terminator)
<marcan>
zsxh: yes
<j`ey>
ok yes I see now, it builds up all the diff variations
<as400[m]>
marcan: what's next on your radar ?
<marcan>
SMC
<marcan>
which is actually required for wifi
Dcow_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<marcan>
I forgot about that, sec
<zsxh>
marcan: Does this need any kernel option? Built the kernel but doesnt actually detect any wifi devices or anything relevant in dmesg
<as400[m]>
marcan: are you planning to stream your work on SMC ?
<marcan>
you need to run that before running linux for the wifi device to show up
<marcan>
zsxh: ^
<marcan>
you do need the BRCMFMAC driver with PCIE support
<marcan>
as400[m]: probably
<ChaosPrincess>
asahi intends to use u-boot for bootloader/picker and for fake efi services, right?
<marcan>
not so much picker, just efi services (nothing fake about them)
<as400[m]>
marcan: thx - great to hear.
<kettenis>
or use u-boot ;)
<as400[m]>
kettenis: btw - for now your u-boot does not work on j314, right ?
<kettenis>
true
<as400[m]>
any plans for the future on this ?
<kettenis>
yes
<as400[m]>
kettenis: thx - nice to hear.
<kettenis>
but I don't have an M1 Pro/Max machine yet
<as400[m]>
kettenis: oh jee, that is a "small" obstacle I guess...
<kettenis>
not yet
<as400[m]>
kettenis: I wonder - is there a place where I can read on state of M1 machines running openbsd ?
<mps>
kettenis: any plan to add internal keyboard to u-boot
<kettenis>
mps: yes
<kettenis>
as400[m]: not really; I don't get paid to do this stuff, so I don't do any reporting ;)
<mps>
kettenis: keyboard in u-boot will be big improvement. thanks
<kettenis>
future asahi reports will likely include a paragraph on OpenBSD though
<as400[m]>
kettenis: great ! That would be awesome.
<zsxh>
marcan: U can only set the BRCMFMAC driver to module, am I doing something wrong? Wrong option maybe?
<zsxh>
s/U/I
<_jannau_>
most likely some of the dependencies are built as module
<zsxh>
That was it, Thank you.
<Redecorating[m]>
I'm getting `ERROR: modpost: "iowrite64" [drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko] undefined!` when building for x86_64, but changing the ifdef on line 566 in pcie.c to false lets it build (but it could be an issue with my kernel config)
<chadmed>
sounds like a config problem, built fine and running right now on my A1708 macbook pro (skylake i5)
<zsxh>
huh, cant get it to work but must be an issue on my part
<chadmed>
i have it as well as its dependencies built as modules. what does dmesg say about it when it tries to load?
chadmed has quit [Remote host closed the connection]
<mps>
so does BRCMFMAC must be compiled in kernel or it could be used as module, not sure I understood backlog here
<zsxh>
j`ey: Yes, I am. Although my m1n1 install is not newest, could that be an issue?
<j`ey>
zsxh: you could try chainload a newer m1n1 to rule it out
Dcow_ has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<zsxh>
Can do in a bit, yes. Will report back
<Redecorating[m]>
mps: module should be fine
<_jannau_>
mps: built-in is more convenient for an externally built and booted kernel
<FireFox317>
remember that you need the firmware in a initramfs when you build the brcmfmac driver in the kernel itself
<FireFox317>
because in my case the brcm driver loads before the rootfs is actually mounted
<zsxh>
Does anyone have a known working kernel config for wifi? Not sure I did it right
<FireFox317>
zsxh, make sure to also enable pcie
jkm has joined #asahi
phire has quit [Ping timeout: 480 seconds]
<mps>
I built it as module (as I have don't use initramfs), 'modprobe brcmfmac' load it and other required modules, but interface is not instantiated and dmesg doesn't shows it tries to load firmware
<kettenis>
does the pci device show up when you do lspci?
<mps>
kettenis: no
<mps>
shows only '00:00.0 PCI bridge: Apple Inc. Device 100c (rev 01)'
<marcan>
Redecorating[m]: if you feel like a bit of a brute force test, you can try changing BRCMF_OTP_MAX_WORDS to 0x800 and base to 0 and words = 0x800
<marcan>
and see what happens; it'll log a ton and will probabl complain a lot, but it might help us find the OTP if it's somewhere unexpected
<zsxh>
marcan: It's an MBA j313. It said broadcom subsidiary device, sorry if misspelled
<Redecorating[m]>
marcan: It's a MacBookPro16,1 with BCM4364 B3 which is rev 4 in lspci. The nvram macos uses is bali with vendor u, antenna X3. Tomorrow I'll see if increasing the words and starting at 0 gets anything.
Guest7760 is now known as svenpeter[m]
<marcan>
zsxh: there should be two broadcom devices (wifi and bluetooth, two functions)
<zsxh>
marcan: Right, there is two
<zsxh>
I assume it should say Kernel driver in use: ...? But it does not.
<marcan>
then the driver isn't loaded or you're missing the pcie bus support
<zsxh>
I built BRCMFMAC and its PCIe support into the kernel, so Im not quite sure why it would be missing
<marcan>
zsxh: *into* the kernel? not as a module?
<marcan>
if you build in the driver then you need to put the firmware in an initramfs, otherwise it will fail to load it on boot
yuyichao has quit [Ping timeout: 480 seconds]
zsxh has quit [Ping timeout: 480 seconds]
yuyichao has joined #asahi
sailorek1234 has quit [Quit: sailorek1234]
<fionera[m]>
kettenis: i tried to add the m1 max dts to your uboot branch for fun and to see if it maybe gives stuff to serial, it doesnt xD
<j`ey>
zimsneexh: you could try enable CONFIG_BRCTRACING
<j`ey>
sorry
<j`ey>
CONFIG_BRCM_TRACING
<Glanzmann>
marcan[m]: I'm on the mini. I turned the mini on it boots to m1n1, I chainload newest m1n1, than I run pcie_enable_devices.py. It appears to be crashing and m1n1 proxy is unresponsive afterwards. See: https://pbot.rmdir.de/u/9S8a8qr9NrLUFfa6F9Twig
<Glanzmann>
Any ideas what I'm doing wrong?
<zimsneexh>
j`ey: Will do. I'll try again
<j`ey>
Glanzmann: are you sure M1N1DEVICE=/dev/ttyACM1 is right?
<Glanzmann>
j`ey: I assume so because I always try until one works. And I'm also chainloading m1n1 using the same serial device (see pastebot).
<j`ey>
Glanzmann: no, look at it: "(nuc) [~/work/m1n1] CE=/dev/ttyACM1 ./proxyclient/tools/chainload.py build/m1n1.macho
<Glanzmann>
j`ey: Thank you. :-) Previously ttyACM device always stayed the same. Don't know why it now is changing after chainloading.
Hotswap has quit [Remote host closed the connection]
<j`ey>
np
<zimsneexh>
j`ey: Enabled the option and now I'm getting kernel logs from brcmfmac. It fails since it's not on initramfs, but i'll try to do that now
<j`ey>
zimsneexh: 👍
<Glanzmann>
Regarding wifi, I'm still on the mini, I chainloaded mini, run pci enable experiment, booted linux, do not have a ramdisk, built brcmfmac, extracted the firmware captures with the latest asahi-installer change. I see the pci device but wifi device does not show up after modprobe brcmfmac. See: https://pbot.rmdir.de/VdsEeKVaWZbh1SM-mQviTw
<zimsneexh>
j`ey: The initrd.gz would have this directory structure, right? /usr/lib/firmware/brcm/ with all the firmware files in that
<j`ey>
I believe so, I haven't done it myself
<j`ey>
thats where it is on the rpi, so
tpw_rules has quit [Ping timeout: 480 seconds]
tpw_rules has joined #asahi
<zimsneexh>
huh, the firmware file(s) it's looking for don't exist on my macOS install, guess i have to update
<j`ey>
zimsneexh: youre running the script from asah-installer repo right?
<j`ey>
that renames the firmware
<zimsneexh>
I am, yes. It's looking for brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m.bin but I dont have that in the extracted firmware from macOS
<j`ey>
when you say "it's" you're talking about Linux right?
<zimsneexh>
Sorry, yes. Linux.
<j`ey>
in macOS you can run ioreg -l | grep RequestedFiles, that will show you which files macOS is using and you should have that in the directory you pass to the firmware py script
<FireFox317>
marcan, i think the driver before your changes retried to get the firmware after 60seconds or so, i dont think that happens currently, and maybe some people are relying on this behaviour (tho they prob shouldnt)
<marcan>
zimsneexh: no /usr
<marcan>
zimsneexh: are you using the asahi-installer copy script?
<marcan>
you cannot use the firmware from macOS directly
<marcan>
it has to be renamed and the nvram files modified
<marcan>
firefox317: huh, I didn't see that code anywhere?
<Glanzmann>
marcan[m]: I tried the mini and the air, both no luck. I used your latest installer script. sending you my dump via msg.
<zimsneexh>
marcan: Yes, I am using the asahi-installer script to get the files.
<j`ey>
oh ok, on my rpi+ubuntu, /lib is a symlink to /usr/lib
<zimsneexh>
It's not ment to be run in 1TR, correct? MacOS is fine, right?
<FireFox317>
marcan, hmm no maybe somehow linux loads the driver again or something (was with a builtin driver btw, not a module)
<Glanzmann>
firefox317: For me brmcfmac is a module.
<Glanzmann>
I manually do a modprobe brmcfmac
<FireFox317>
Glanzmann, sure, you can also build it as amodule
<marcan>
Glanzmann: I am 100% certain it works on the mini, as I tested it there
<Glanzmann>
marcan: Can you please upload me your kernel and module tree or your .config, than I rebuild try again.
<marcan>
Glanzmann: did you enable brcmfmac and the pcie backend?
<marcan>
zimsneexh: macOS is fine, can you paste the stdout from the copy script?
<Glanzmann>
marcan: brcmfmac for sure, About the pcie backend I'm not sure.
<marcan>
it's right after brcmfmac in the menuconfig
kit_ty_kate has joined #asahi
yuyichao_ has joined #asahi
<zimsneexh>
marcan: Of course, one minute. It's not MacOS 12.1 yet, however.
<marcan>
hopefully that doesn't matter
<sorear>
TIL there are cases where you need to build a modular kernel that don't come down to "extremely little ram" or "bootloader limitations". am curious if there is a list of other drivers that are limited in this way when compiled in
<marcan>
it's not really a limitation
<marcan>
it works fine if you use an initramfs for the firmware
<marcan>
you could also re-bind the device manually after boot to try again
yuyichao has quit [Ping timeout: 480 seconds]
<marcan>
it's not exactly surprising that if you build in drivers and not the firmware they require, things can break
<marcan>
hence initramfs
<ChaosPrincess>
you can also build firmware directly into kernel, there is a config field for that
<marcan>
yes
<ChaosPrincess>
but that makes it non-redistributable and other unpleasant stuff
<FireFox317>
so my initramfs should contain usr/lib/firmware/brcm/brcm* right?
<marcan>
either way ~all distros are going to be building this as a module, and if you're building your own kernels you can handle building an initramfs to go along with it
<j`ey>
firefox317: no usr
<FireFox317>
j`ey, okay so usr/firmware/brcm/brcm*
<j`ey>
firefox317: no usr, not no lib!
<mps>
hm, why /usr/firmware? common is /lib/firmware
<marcan>
zimsneexh: it should be loading brcm/brcmfmac4378b1-pcie.apple,shikoku.bin and brcm/brcmfmac4378b1-pcie.apple,shikoku-RASP-m.txt and brcm/brcmfmac4378b1-pcie.apple,shikoku.clm_blob
<FireFox317>
j`ey, oh sorry, i thought you meant dont include usr in that patch
<FireFox317>
my bad
<marcan>
note that it tries many variations on firmware names, since the copy script reduces them to a common denominator
<marcan>
zimsneexh: it's spending 60 seconds per firmware load. I think you have some config option that makes it ask userspace for firmware, and you don't have userspace listening
<marcan>
it's not actually failing, it's just taking forever to go through all the filenames
<marcan>
CONFIG_FW_LOADER_USER_HELPER_FALLBACK and CONFIG_FW_LOADER_USER_HELPER
<marcan>
probably disable the first one, and maybe also the second one altogether
<marcan>
I've been running with a million debugs enabled so I haven't experienced the "normal" dmesg :p
<zimsneexh>
It still panics on MBA for me, but i'll try to clean build the kernel first, just in case..
<Glanzmann>
zimsneexh: I try the macbook air right now. Give me a second. Here my config: https://tg.st/u/.config
<marcan>
same panic?
<zimsneexh>
yep.
<marcan>
clean build should never be necessary, more likely you didn't pull properly or you didn't copy the kernel or something silly like that
<Glanzmann>
marcan: I'll run a 24 hour stress test on the mini with wifi and report back.
<marcan>
(assuming this isn't another bug)
<marcan>
Glanzmann: thanks
jmr2 has joined #asahi
<marcan>
I moved the problem structure from stack to heap and I don't think there's anything overflowable on the stack left, so... I think that's probably you're still running the old one :)
<jmr2>
Glanzmann: you might want to disconnect your wired connection, to make your results more significant.
<Glanzmann>
marcan: Thank you for this project. :-)
<Glanzmann>
jmr2: I'll do so. I plan to run iperf3 in an endless loop with 2 and 5 mhz.
<marcan>
ghz, hopefully :p
<Glanzmann>
jmr2: I only had so many wired connection because I was not sure if I screwed up the kernel config or the system was crashing.
<Glanzmann>
marcan: Yes ghz. I got a new wifi 6 access point which can go upto 1200 Mbits (a little bit over 100 MB/s).
<marcan>
and yeah, some "general use / perf tests" would be good; I haven't really stressed it yet. it would at least validate that 1) performance is good with all the proper config files we use, and 2) it's reasonably stable, no weirdo random crash bugs
<marcan>
I still need to take a look at country codes, not sure what the situation is there yet
<marcan>
whether we're supposed to set that from somewhere or what
<marcan>
once we confirm this isn't blatantly broken and I add T2 support though, I'll send an RFC to the maintainers anyway, see what they have to say
<jmr2>
marcan: I saw your previous comment regarding country code. It's not clear from me if it's stored somewhere or obtained from one of the questions asked during MacOS setup.
<jmr2>
*for
<FireFox317>
marcan, i get this in my dmesg now: ieee80211 phy0: brcmf_p2p_set_firmware: failed to update device address ret -52
jmr2 has quit [Quit: Page closed]
<FireFox317>
not completely sure if it is related, my rootfs might also be screwed, or i dont have the correct configs enabled
<marcan>
jmr2: sometimes it is set from the AP's country code too
<marcan>
firefox317: that's normal
<marcan>
should still work
<marcan>
(AFAIK)
<FireFox317>
okay, will try some stuff
<Glanzmann>
firefox317: If I should upload you my rootfs, let me know (debian testing)
<Glanzmann>
does someone know which driver I need for wpa supplicant e.g.? nl80211
<FireFox317>
marcan, watching youtube on firefox now, so it defintely works :)
<Glanzmann>
Can I capture the firmware on the mini and use it on the air or should I recapture on the macbook air?
<Glanzmann>
I also captured on the air but I'm not sure if I captured with the latest asahi-installer commit, so recaptyuring to be on the safe side
<Glanzmann>
Oh and does someone managed to get the keyboard working with the 'wifi' branch on the air? If so which config options do I need (last time I tried the air that was with rc upstream kernel and jannaus config which worked fine).
<mps>
Glanzmann: HID_APPLE iirc
Raqbit4 has joined #asahi
<Glanzmann>
mps: I see HID_APPLE is set but CONFIG_SPI_HID_APPLE not. I need that, too, don't I?
<mps>
yes
<mps>
at least I have it enabled and keyboard works
yuyichao has joined #asahi
<mps>
on mbp
<Glanzmann>
Thanks, I'll fix that.
Raqbit has quit [Ping timeout: 480 seconds]
Raqbit4 is now known as Raqbit
<zimsneexh>
marcan: It does work on MBA, must've just used the wrong Image.gz or something. Great job!
yuyichao_ has quit [Ping timeout: 480 seconds]
<Glanzmann>
wifi on the macbook air also works for me.
<Glanzmann>
For me it was forgetting to extracing the firmware ...
<Glanzmann>
marcan: Thank you again for the wifi, the support and the whole project.
<zimsneexh>
Glanzmann: Do you have the firmware in an initrd?
<marcan>
the wifi branch is out of date WRT other patchsets like the touchpad
<marcan>
please don't bother testing anything other than wifi on that one
<marcan>
I will be merging in updates and pushing to asahi later
<Glanzmann>
marcan: I see.
<Glanzmann>
zimsneexh: I use debian testing at the moment, works good.
<zimsneexh>
Wifi seems good, getting about 440mbit/s to my relatively cheapo 5ghz accesspoint
<zimsneexh>
That's about what I'd expect
<mps>
Glanzmann: you run it with hypervisor?
<marcan>
nice :)
<zimsneexh>
I'll let this run for a while, to see if it's stable
<marcan>
Glanzmann: the firmware is universal, it includes everything for every mac
<marcan>
(even T2 ones)
<marcan>
that's why it's like 170 files
<marcan>
or more than 1000 in the original apple tree
<marcan>
presumably firmware versions do change e.g. to fix security bugs, but I'd hope they don't introduce breaking changes
<marcan>
either way brcmfmac already has several firmware version feature gate mechanisms and I just added yet another one
<marcan>
so we can deal with that if/when it happens
<SamAdams[m]>
Is there a plan to enable pcie devices and allow for the wifi-firmware for direct payload in m1n1, so we can try out the Wi-Fi, or will we need to chainload it?
<marcan>
yes
<marcan>
that requires the SMC driver which does not exist yet
<marcan>
that's coming up next after I spend tomorrow making this work on T2 too so I can submit it
<zimsneexh>
SMC would also be battery status and such right?
<j`ey>
yep
<marcan>
yes
<j`ey>
and 1000 other things
<marcan>
I intend to build it as subdrivers, so we can incrementally add features
<marcan>
gpio would be one, that's the wifi enable bit (among others)
<marcan>
battery management would be another
<j`ey>
(not joking there's ~1300 smc "keys" on the mba)
<marcan>
fan control another, temperatures another, etc
<Glanzmann>
I see, cool.
<kettenis>
I've got the basic battery stuff figured out
<marcan>
I'm going to start with the critical ones (gpio, battery) and then we'll see about adding more features as we go along
<marcan>
fwiw the API is very simple and there will definitely be some kind of debug interface
<SamAdams[m]>
Yes! That would be cool. Kind of like virtualSMC for Hackintosh.
<marcan>
so working out SMC features and adding subdrivers is good territory for less experienced folks to help out
<zimsneexh>
Just out of curiousity - Will you be streaming that work?
<marcan>
especially once we have a couple examples
<marcan>
kettenis: awesome :)
Major_Biscuit has joined #asahi
<marcan>
would be nice if you can write that out somewhere, I assume it's not too complicated?