In what languages can firmware be written?
Embedded firmware is still software, so it is possible to write it in any Turing Complete language given sufficient time and memory (strictly speaking a Turing complete language has infinite resources). We often refer to the languages we use as Turing complete even though the machines do not have infinite resources.

Therefore a program could be written in native machine code, assembler (both of which require quite detailed knowledge of the internals of the device) or a higher level language (which may be compiled or interpreted).

The only real limitation is the available toolset.

Compiled languages are quite efficient but sometimes don't do precisely what you really want (optmisers will strip out instructions that it believes are not necessary even when you think they are although there are ways around that).

The only way to define precisely what is actually run is to write the code with a non-optimising assembler or by hand assembling machine code. This may or may not be more efficient than a compiled solution (it can be depending on how you structure the code).

In some circumstances, we use a compiler and hand tweak the assembly output (not for the faint of heart) in some very demanding situataions.

So the answer is that there is no technical reason that any language could not be used.